Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt46
-rw-r--r--build_files/build_environment/cmake/sndfile.cmake12
-rw-r--r--build_files/build_environment/cmake/versions.cmake6
-rwxr-xr-xbuild_files/build_environment/install_deps.sh18
-rw-r--r--build_files/buildbot/config/blender_linux.cmake4
-rw-r--r--build_files/cmake/Modules/FindSndFile.cmake40
-rw-r--r--build_files/cmake/macros.cmake13
-rw-r--r--build_files/cmake/platform/platform_apple.cmake10
-rw-r--r--build_files/cmake/platform/platform_unix.cmake2
-rw-r--r--build_files/cmake/platform/platform_win32.cmake10
-rw-r--r--extern/CMakeLists.txt5
-rw-r--r--extern/audaspace/AUTHORS16
-rw-r--r--extern/audaspace/CHANGES115
-rw-r--r--extern/audaspace/CMakeLists.txt983
-rw-r--r--extern/audaspace/INSTALL107
-rw-r--r--extern/audaspace/LICENSE202
-rw-r--r--extern/audaspace/README.md47
-rw-r--r--extern/audaspace/bindings/C/AUD_Device.cpp336
-rw-r--r--extern/audaspace/bindings/C/AUD_Device.h258
-rw-r--r--extern/audaspace/bindings/C/AUD_DynamicMusic.cpp144
-rw-r--r--extern/audaspace/bindings/C/AUD_DynamicMusic.h145
-rw-r--r--extern/audaspace/bindings/C/AUD_HRTF.cpp50
-rw-r--r--extern/audaspace/bindings/C/AUD_HRTF.h48
-rw-r--r--extern/audaspace/bindings/C/AUD_Handle.cpp384
-rw-r--r--extern/audaspace/bindings/C/AUD_Handle.h308
-rw-r--r--extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp44
-rw-r--r--extern/audaspace/bindings/C/AUD_ImpulseResponse.h40
-rw-r--r--extern/audaspace/bindings/C/AUD_PlaybackManager.cpp94
-rw-r--r--extern/audaspace/bindings/C/AUD_PlaybackManager.h103
-rw-r--r--extern/audaspace/bindings/C/AUD_Sequence.cpp315
-rw-r--r--extern/audaspace/bindings/C/AUD_Sequence.h338
-rw-r--r--extern/audaspace/bindings/C/AUD_Sound.cpp709
-rw-r--r--extern/audaspace/bindings/C/AUD_Sound.h370
-rw-r--r--extern/audaspace/bindings/C/AUD_Source.cpp84
-rw-r--r--extern/audaspace/bindings/C/AUD_Source.h84
-rw-r--r--extern/audaspace/bindings/C/AUD_Special.cpp420
-rw-r--r--extern/audaspace/bindings/C/AUD_Special.h138
-rw-r--r--extern/audaspace/bindings/C/AUD_ThreadPool.cpp42
-rw-r--r--extern/audaspace/bindings/C/AUD_ThreadPool.h40
-rw-r--r--extern/audaspace/bindings/C/AUD_Types.h179
-rw-r--r--extern/audaspace/bindings/doc/conf.py.in261
-rw-r--r--extern/audaspace/bindings/doc/device.rst7
-rw-r--r--extern/audaspace/bindings/doc/handle.rst7
-rw-r--r--extern/audaspace/bindings/doc/index.rst35
-rw-r--r--extern/audaspace/bindings/doc/sequence.rst7
-rw-r--r--extern/audaspace/bindings/doc/sequence_entry.rst7
-rw-r--r--extern/audaspace/bindings/doc/sound.rst7
-rw-r--r--extern/audaspace/bindings/doc/tutorials.rst166
-rw-r--r--extern/audaspace/bindings/python/PyAPI.cpp231
-rw-r--r--extern/audaspace/bindings/python/PyAPI.h45
-rw-r--r--extern/audaspace/bindings/python/PyDevice.cpp785
-rw-r--r--extern/audaspace/bindings/python/PyDevice.h33
-rw-r--r--extern/audaspace/bindings/python/PyDynamicMusic.cpp467
-rw-r--r--extern/audaspace/bindings/python/PyDynamicMusic.h33
-rw-r--r--extern/audaspace/bindings/python/PyHRTF.cpp247
-rw-r--r--extern/audaspace/bindings/python/PyHRTF.h33
-rw-r--r--extern/audaspace/bindings/python/PyHandle.cpp1126
-rw-r--r--extern/audaspace/bindings/python/PyHandle.h33
-rw-r--r--extern/audaspace/bindings/python/PyImpulseResponse.cpp137
-rw-r--r--extern/audaspace/bindings/python/PyImpulseResponse.h33
-rw-r--r--extern/audaspace/bindings/python/PyPlaybackManager.cpp389
-rw-r--r--extern/audaspace/bindings/python/PyPlaybackManager.h33
-rw-r--r--extern/audaspace/bindings/python/PySequence.cpp655
-rw-r--r--extern/audaspace/bindings/python/PySequence.h33
-rw-r--r--extern/audaspace/bindings/python/PySequenceEntry.cpp740
-rw-r--r--extern/audaspace/bindings/python/PySequenceEntry.h33
-rw-r--r--extern/audaspace/bindings/python/PySound.cpp1966
-rw-r--r--extern/audaspace/bindings/python/PySound.h33
-rw-r--r--extern/audaspace/bindings/python/PySource.cpp260
-rw-r--r--extern/audaspace/bindings/python/PySource.h33
-rw-r--r--extern/audaspace/bindings/python/PyThreadPool.cpp134
-rw-r--r--extern/audaspace/bindings/python/PyThreadPool.h33
-rw-r--r--extern/audaspace/bindings/python/examples/binaural.py13
-rw-r--r--extern/audaspace/bindings/python/examples/convolution.py10
-rw-r--r--extern/audaspace/bindings/python/examples/dynamicmusic.py20
-rw-r--r--extern/audaspace/bindings/python/examples/playbackmanager.py27
-rw-r--r--extern/audaspace/bindings/python/examples/player.py7
-rw-r--r--extern/audaspace/bindings/python/examples/randomSounds.py21
-rw-r--r--extern/audaspace/bindings/python/examples/simple.py7
-rw-r--r--extern/audaspace/bindings/python/examples/siren.py19
-rw-r--r--extern/audaspace/bindings/python/examples/siren2.py23
-rw-r--r--extern/audaspace/bindings/python/examples/tetris.py66
-rw-r--r--extern/audaspace/bindings/python/examples/tetris2.py64
-rw-r--r--extern/audaspace/bindings/python/examples/tetris3.py63
-rw-r--r--extern/audaspace/bindings/python/setup.py.in61
-rw-r--r--extern/audaspace/blender_config.cmake26
-rw-r--r--extern/audaspace/config/Audaspace.h.in131
-rw-r--r--extern/audaspace/include/Exception.h185
-rw-r--r--extern/audaspace/include/IReader.h (renamed from intern/audaspace/intern/AUD_IReader.h)57
-rw-r--r--extern/audaspace/include/ISound.h57
-rw-r--r--extern/audaspace/include/devices/DefaultSynchronizer.h44
-rw-r--r--extern/audaspace/include/devices/DeviceManager.h129
-rw-r--r--extern/audaspace/include/devices/I3DDevice.h142
-rw-r--r--extern/audaspace/include/devices/I3DHandle.h (renamed from intern/audaspace/intern/AUD_I3DHandle.h)110
-rw-r--r--extern/audaspace/include/devices/IDevice.h123
-rw-r--r--extern/audaspace/include/devices/IDeviceFactory.h72
-rw-r--r--extern/audaspace/include/devices/IHandle.h (renamed from intern/audaspace/intern/AUD_IHandle.h)80
-rw-r--r--extern/audaspace/include/devices/ISynchronizer.h92
-rw-r--r--extern/audaspace/include/devices/NULLDevice.h96
-rw-r--r--extern/audaspace/include/devices/ReadDevice.h82
-rw-r--r--extern/audaspace/include/devices/SoftwareDevice.h (renamed from intern/audaspace/intern/AUD_SoftwareDevice.h)194
-rw-r--r--extern/audaspace/include/file/File.h74
-rw-r--r--extern/audaspace/include/file/FileManager.h95
-rw-r--r--extern/audaspace/include/file/FileWriter.h78
-rw-r--r--extern/audaspace/include/file/IFileInput.h60
-rw-r--r--extern/audaspace/include/file/IFileOutput.h52
-rw-r--r--extern/audaspace/include/file/IWriter.h89
-rw-r--r--extern/audaspace/include/fx/ADSR.h121
-rw-r--r--extern/audaspace/include/fx/ADSRReader.h101
-rw-r--r--extern/audaspace/include/fx/Accumulator.h79
-rw-r--r--extern/audaspace/include/fx/BaseIIRFilterReader.h (renamed from intern/audaspace/FX/AUD_BaseIIRFilterReader.h)70
-rw-r--r--extern/audaspace/include/fx/BinauralReader.h223
-rw-r--r--extern/audaspace/include/fx/BinauralSound.h119
-rw-r--r--extern/audaspace/include/fx/Butterworth.h48
-rw-r--r--extern/audaspace/include/fx/ButterworthCalculator.h55
-rw-r--r--extern/audaspace/include/fx/CallbackIIRFilterReader.h88
-rw-r--r--extern/audaspace/include/fx/Convolver.h177
-rw-r--r--extern/audaspace/include/fx/ConvolverReader.h198
-rw-r--r--extern/audaspace/include/fx/ConvolverSound.h100
-rw-r--r--extern/audaspace/include/fx/Delay.h60
-rw-r--r--extern/audaspace/include/fx/DelayReader.h63
-rw-r--r--extern/audaspace/include/fx/DynamicIIRFilter.h54
-rw-r--r--extern/audaspace/include/fx/DynamicIIRFilterReader.h60
-rw-r--r--extern/audaspace/include/fx/DynamicMusic.h235
-rw-r--r--extern/audaspace/include/fx/Effect.h76
-rw-r--r--extern/audaspace/include/fx/EffectReader.h68
-rw-r--r--extern/audaspace/include/fx/Envelope.h93
-rw-r--r--extern/audaspace/include/fx/FFTConvolver.h196
-rw-r--r--extern/audaspace/include/fx/Fader.h87
-rw-r--r--extern/audaspace/include/fx/FaderReader.h77
-rw-r--r--extern/audaspace/include/fx/HRTF.h108
-rw-r--r--extern/audaspace/include/fx/HRTFLoader.h99
-rw-r--r--extern/audaspace/include/fx/Highpass.h49
-rw-r--r--extern/audaspace/include/fx/HighpassCalculator.h61
-rw-r--r--extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h50
-rw-r--r--extern/audaspace/include/fx/IIRFilter.h63
-rw-r--r--extern/audaspace/include/fx/IIRFilterReader.h70
-rw-r--r--extern/audaspace/include/fx/ImpulseResponse.h108
-rw-r--r--extern/audaspace/include/fx/Limiter.h73
-rw-r--r--extern/audaspace/include/fx/LimiterReader.h65
-rw-r--r--extern/audaspace/include/fx/Loop.h62
-rw-r--r--extern/audaspace/include/fx/LoopReader.h65
-rw-r--r--extern/audaspace/include/fx/Lowpass.h49
-rw-r--r--extern/audaspace/include/fx/LowpassCalculator.h61
-rw-r--r--extern/audaspace/include/fx/MutableReader.h71
-rw-r--r--extern/audaspace/include/fx/MutableSound.h58
-rw-r--r--extern/audaspace/include/fx/Pitch.h55
-rw-r--r--extern/audaspace/include/fx/PitchReader.h67
-rw-r--r--extern/audaspace/include/fx/PlaybackCategory.h127
-rw-r--r--extern/audaspace/include/fx/PlaybackManager.h156
-rw-r--r--extern/audaspace/include/fx/Reverse.h50
-rw-r--r--extern/audaspace/include/fx/ReverseReader.h65
-rw-r--r--extern/audaspace/include/fx/SoundList.h110
-rw-r--r--extern/audaspace/include/fx/Source.h109
-rw-r--r--extern/audaspace/include/fx/Sum.h49
-rw-r--r--extern/audaspace/include/fx/Threshold.h78
-rw-r--r--extern/audaspace/include/fx/Volume.h63
-rw-r--r--extern/audaspace/include/fx/VolumeReader.h70
-rw-r--r--extern/audaspace/include/fx/VolumeSound.h74
-rw-r--r--extern/audaspace/include/fx/VolumeStorage.h71
-rw-r--r--extern/audaspace/include/generator/Sawtooth.h66
-rw-r--r--extern/audaspace/include/generator/SawtoothReader.h86
-rw-r--r--extern/audaspace/include/generator/Silence.h48
-rw-r--r--extern/audaspace/include/generator/SilenceReader.h59
-rw-r--r--extern/audaspace/include/generator/Sine.h67
-rw-r--r--extern/audaspace/include/generator/SineReader.h77
-rw-r--r--extern/audaspace/include/generator/Square.h67
-rw-r--r--extern/audaspace/include/generator/SquareReader.h86
-rw-r--r--extern/audaspace/include/generator/Triangle.h67
-rw-r--r--extern/audaspace/include/generator/TriangleReader.h86
-rw-r--r--extern/audaspace/include/plugin/PluginManager.h81
-rw-r--r--extern/audaspace/include/respec/ChannelMapper.h51
-rw-r--r--extern/audaspace/include/respec/ChannelMapperReader.h151
-rw-r--r--extern/audaspace/include/respec/Converter.h51
-rw-r--r--extern/audaspace/include/respec/ConverterFunctions.h377
-rw-r--r--extern/audaspace/include/respec/ConverterReader.h67
-rw-r--r--extern/audaspace/include/respec/JOSResample.h50
-rw-r--r--extern/audaspace/include/respec/JOSResampleReader.h129
-rw-r--r--extern/audaspace/include/respec/LinearResample.h50
-rw-r--r--extern/audaspace/include/respec/LinearResampleReader.h80
-rw-r--r--extern/audaspace/include/respec/Mixer.h123
-rw-r--r--extern/audaspace/include/respec/ResampleReader.h61
-rw-r--r--extern/audaspace/include/respec/Specification.h138
-rw-r--r--extern/audaspace/include/respec/SpecsChanger.h74
-rw-r--r--extern/audaspace/include/sequence/AnimateableProperty.h129
-rw-r--r--extern/audaspace/include/sequence/Double.h60
-rw-r--r--extern/audaspace/include/sequence/DoubleReader.h77
-rw-r--r--extern/audaspace/include/sequence/PingPong.h50
-rw-r--r--extern/audaspace/include/sequence/Sequence.h (renamed from intern/audaspace/intern/AUD_SequencerFactory.h)114
-rw-r--r--extern/audaspace/include/sequence/SequenceData.h (renamed from intern/audaspace/intern/AUD_Sequencer.h)115
-rw-r--r--extern/audaspace/include/sequence/SequenceEntry.h (renamed from intern/audaspace/intern/AUD_SequencerEntry.h)116
-rw-r--r--extern/audaspace/include/sequence/SequenceReader.h94
-rw-r--r--extern/audaspace/include/sequence/Superpose.h62
-rw-r--r--extern/audaspace/include/sequence/SuperposeReader.h79
-rw-r--r--extern/audaspace/include/util/Barrier.h78
-rw-r--r--extern/audaspace/include/util/Buffer.h87
-rw-r--r--extern/audaspace/include/util/BufferReader.h76
-rw-r--r--extern/audaspace/include/util/FFTPlan.h120
-rw-r--r--extern/audaspace/include/util/ILockable.h46
-rw-r--r--extern/audaspace/include/util/Math3D.h (renamed from intern/audaspace/intern/AUD_3DMath.h)102
-rw-r--r--extern/audaspace/include/util/StreamBuffer.h85
-rw-r--r--extern/audaspace/include/util/ThreadPool.h119
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.cpp63
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.h60
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp397
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.h184
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp427
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h145
-rw-r--r--extern/audaspace/plugins/jack/JackDevice.cpp385
-rw-r--r--extern/audaspace/plugins/jack/JackDevice.h (renamed from intern/audaspace/jack/AUD_JackDevice.h)115
-rw-r--r--extern/audaspace/plugins/jack/JackLibrary.cpp59
-rw-r--r--extern/audaspace/plugins/jack/JackLibrary.h48
-rw-r--r--extern/audaspace/plugins/jack/JackSymbols.h45
-rw-r--r--extern/audaspace/plugins/jack/JackSynchronizer.cpp58
-rw-r--r--extern/audaspace/plugins/jack/JackSynchronizer.h59
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFile.cpp62
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFile.h60
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileReader.cpp161
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileReader.h125
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileWriter.cpp128
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileWriter.h84
-rw-r--r--extern/audaspace/plugins/openal/OpenALDevice.cpp1490
-rw-r--r--extern/audaspace/plugins/openal/OpenALDevice.h (renamed from intern/audaspace/OpenAL/AUD_OpenALDevice.h)198
-rw-r--r--extern/audaspace/plugins/openal/OpenALReader.cpp96
-rw-r--r--extern/audaspace/plugins/openal/OpenALReader.h83
-rw-r--r--extern/audaspace/plugins/sdl/SDLDevice.cpp156
-rw-r--r--extern/audaspace/plugins/sdl/SDLDevice.h82
-rw-r--r--extern/audaspace/src/Exception.cpp110
-rw-r--r--extern/audaspace/src/devices/DefaultSynchronizer.cpp49
-rw-r--r--extern/audaspace/src/devices/DeviceManager.cpp117
-rw-r--r--extern/audaspace/src/devices/NULLDevice.cpp193
-rw-r--r--extern/audaspace/src/devices/ReadDevice.cpp69
-rw-r--r--extern/audaspace/src/devices/SoftwareDevice.cpp989
-rw-r--r--extern/audaspace/src/file/File.cpp45
-rw-r--r--extern/audaspace/src/file/FileManager.cpp88
-rw-r--r--extern/audaspace/src/file/FileWriter.cpp95
-rw-r--r--extern/audaspace/src/fx/ADSR.cpp73
-rw-r--r--extern/audaspace/src/fx/ADSRReader.cpp115
-rw-r--r--extern/audaspace/src/fx/Accumulator.cpp54
-rw-r--r--extern/audaspace/src/fx/BaseIIRFilterReader.cpp125
-rw-r--r--extern/audaspace/src/fx/BinauralReader.cpp255
-rw-r--r--extern/audaspace/src/fx/BinauralSound.cpp60
-rw-r--r--extern/audaspace/src/fx/Butterworth.cpp28
-rw-r--r--extern/audaspace/src/fx/ButterworthCalculator.cpp54
-rw-r--r--extern/audaspace/src/fx/CallbackIIRFilterReader.cpp38
-rw-r--r--extern/audaspace/src/fx/Convolver.cpp156
-rw-r--r--extern/audaspace/src/fx/ConvolverReader.cpp203
-rw-r--r--extern/audaspace/src/fx/ConvolverSound.cpp50
-rw-r--r--extern/audaspace/src/fx/Delay.cpp38
-rw-r--r--extern/audaspace/src/fx/DelayReader.cpp87
-rw-r--r--extern/audaspace/src/fx/DynamicIIRFilter.cpp35
-rw-r--r--extern/audaspace/src/fx/DynamicIIRFilterReader.cpp36
-rw-r--r--extern/audaspace/src/fx/DynamicMusic.cpp346
-rw-r--r--extern/audaspace/src/fx/Effect.cpp35
-rw-r--r--extern/audaspace/src/fx/EffectReader.cpp60
-rw-r--r--extern/audaspace/src/fx/Envelope.cpp71
-rw-r--r--extern/audaspace/src/fx/FFTConvolver.cpp214
-rw-r--r--extern/audaspace/src/fx/Fader.cpp49
-rw-r--r--extern/audaspace/src/fx/FaderReader.cpp76
-rw-r--r--extern/audaspace/src/fx/HRTF.cpp122
-rw-r--r--extern/audaspace/src/fx/HRTFLoaderUnix.cpp89
-rw-r--r--extern/audaspace/src/fx/HRTFLoaderWindows.cpp93
-rw-r--r--extern/audaspace/src/fx/Highpass.cpp28
-rw-r--r--extern/audaspace/src/fx/HighpassCalculator.cpp43
-rw-r--r--extern/audaspace/src/fx/IIRFilter.cpp32
-rw-r--r--extern/audaspace/src/fx/IIRFilterReader.cpp53
-rw-r--r--extern/audaspace/src/fx/ImpulseResponse.cpp97
-rw-r--r--extern/audaspace/src/fx/Limiter.cpp45
-rw-r--r--extern/audaspace/src/fx/LimiterReader.cpp (renamed from intern/audaspace/FX/AUD_LimiterReader.cpp)70
-rw-r--r--extern/audaspace/src/fx/Loop.cpp38
-rw-r--r--extern/audaspace/src/fx/LoopReader.cpp91
-rw-r--r--extern/audaspace/src/fx/Lowpass.cpp27
-rw-r--r--extern/audaspace/src/fx/LowpassCalculator.cpp43
-rw-r--r--extern/audaspace/src/fx/MutableReader.cpp64
-rw-r--r--extern/audaspace/src/fx/MutableSound.cpp35
-rw-r--r--extern/audaspace/src/fx/Pitch.cpp33
-rw-r--r--extern/audaspace/src/fx/PitchReader.cpp44
-rw-r--r--extern/audaspace/src/fx/PlaybackCategory.cpp144
-rw-r--r--extern/audaspace/src/fx/PlaybackManager.cpp186
-rw-r--r--extern/audaspace/src/fx/Reverse.cpp32
-rw-r--r--extern/audaspace/src/fx/ReverseReader.cpp88
-rw-r--r--extern/audaspace/src/fx/SoundList.cpp84
-rw-r--r--extern/audaspace/src/fx/Source.cpp71
-rw-r--r--extern/audaspace/src/fx/Sum.cpp36
-rw-r--r--extern/audaspace/src/fx/Threshold.cpp54
-rw-r--r--extern/audaspace/src/fx/Volume.cpp41
-rw-r--r--extern/audaspace/src/fx/VolumeReader.cpp60
-rw-r--r--extern/audaspace/src/fx/VolumeSound.cpp45
-rw-r--r--extern/audaspace/src/fx/VolumeStorage.cpp39
-rw-r--r--extern/audaspace/src/generator/Sawtooth.cpp38
-rw-r--r--extern/audaspace/src/generator/SawtoothReader.cpp83
-rw-r--r--extern/audaspace/src/generator/Silence.cpp31
-rw-r--r--extern/audaspace/src/generator/SilenceReader.cpp63
-rw-r--r--extern/audaspace/src/generator/Sine.cpp38
-rw-r--r--extern/audaspace/src/generator/SineReader.cpp75
-rw-r--r--extern/audaspace/src/generator/Square.cpp38
-rw-r--r--extern/audaspace/src/generator/SquareReader.cpp83
-rw-r--r--extern/audaspace/src/generator/Triangle.cpp38
-rw-r--r--extern/audaspace/src/generator/TriangleReader.cpp83
-rw-r--r--extern/audaspace/src/plugin/PluginManagerUnix.cpp.in98
-rw-r--r--extern/audaspace/src/plugin/PluginManagerWindows.cpp.in101
-rw-r--r--extern/audaspace/src/respec/ChannelMapper.cpp35
-rw-r--r--extern/audaspace/src/respec/ChannelMapperReader.cpp379
-rw-r--r--extern/audaspace/src/respec/Converter.cpp38
-rw-r--r--extern/audaspace/src/respec/ConverterFunctions.cpp464
-rw-r--r--extern/audaspace/src/respec/ConverterReader.cpp68
-rw-r--r--extern/audaspace/src/respec/JOSResample.cpp33
-rw-r--r--extern/audaspace/src/respec/JOSResampleReader.cpp (renamed from intern/audaspace/intern/AUD_JOSResampleReader.cpp)159
-rw-r--r--extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp (renamed from intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp)48
-rw-r--r--extern/audaspace/src/respec/LinearResample.cpp32
-rw-r--r--extern/audaspace/src/respec/LinearResampleReader.cpp174
-rw-r--r--extern/audaspace/src/respec/Mixer.cpp112
-rw-r--r--extern/audaspace/src/respec/ResampleReader.cpp36
-rw-r--r--extern/audaspace/src/respec/SpecsChanger.cpp42
-rw-r--r--extern/audaspace/src/sequence/AnimateableProperty.cpp217
-rw-r--r--extern/audaspace/src/sequence/Double.cpp35
-rw-r--r--extern/audaspace/src/sequence/DoubleReader.cpp102
-rw-r--r--extern/audaspace/src/sequence/PingPong.cpp36
-rw-r--r--extern/audaspace/src/sequence/Sequence.cpp113
-rw-r--r--extern/audaspace/src/sequence/SequenceData.cpp172
-rw-r--r--extern/audaspace/src/sequence/SequenceEntry.cpp256
-rw-r--r--extern/audaspace/src/sequence/SequenceHandle.cpp (renamed from intern/audaspace/intern/AUD_SequencerHandle.cpp)96
-rw-r--r--extern/audaspace/src/sequence/SequenceHandle.h (renamed from intern/audaspace/intern/AUD_SequencerHandle.h)71
-rw-r--r--extern/audaspace/src/sequence/SequenceReader.cpp198
-rw-r--r--extern/audaspace/src/sequence/Superpose.cpp35
-rw-r--r--extern/audaspace/src/sequence/SuperposeReader.cpp95
-rw-r--r--extern/audaspace/src/util/Barrier.cpp42
-rw-r--r--extern/audaspace/src/util/Buffer.cpp72
-rw-r--r--extern/audaspace/src/util/BufferReader.cpp80
-rw-r--r--extern/audaspace/src/util/FFTPlan.cpp66
-rw-r--r--extern/audaspace/src/util/StreamBuffer.cpp83
-rw-r--r--extern/audaspace/src/util/ThreadPool.cpp60
-rw-r--r--intern/audaspace/CMakeLists.txt304
-rw-r--r--intern/audaspace/COPYING339
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp64
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h69
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.cpp5
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.h10
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp137
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.cpp38
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.h20
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp39
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h54
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp51
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h87
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp48
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp96
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h70
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp112
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h84
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h58
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.h54
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp45
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h82
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp69
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h74
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp82
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h85
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp60
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h92
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp86
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h76
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp39
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h56
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h71
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp65
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h73
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp55
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h79
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h71
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp47
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h68
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp101
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h72
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp38
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp46
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h56
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h61
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp54
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h73
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp48
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.h58
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp42
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h56
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp105
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h72
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp66
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h70
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp45
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.h68
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.cpp105
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.h85
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp50
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h69
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1647
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp2922
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h74
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.cpp97
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.h86
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp42
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h57
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp150
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h103
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp55
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h78
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp483
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h169
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp395
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h160
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.cpp75
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.h92
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.cpp127
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.h102
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.cpp247
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.h128
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp80
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h93
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp90
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.h81
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp1323
-rw-r--r--intern/audaspace/intern/AUD_C-API.h822
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp45
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h57
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp378
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h136
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp47
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h57
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp472
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h128
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp77
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h73
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp84
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h76
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.cpp131
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.h82
-rw-r--r--intern/audaspace/intern/AUD_I3DDevice.h122
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h120
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h61
-rw-r--r--intern/audaspace/intern/AUD_ILockable.h21
-rw-r--r--intern/audaspace/intern/AUD_IWriter.h67
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.cpp42
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.h56
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleReader.h135
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp42
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h56
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp186
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h86
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp121
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h114
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp52
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h79
-rw-r--r--intern/audaspace/intern/AUD_MutexLock.h24
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp159
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h84
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp78
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.h88
-rw-r--r--intern/audaspace/intern/AUD_ResampleFactory.h37
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.cpp45
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.h66
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.cpp177
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.cpp319
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp123
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp204
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.h99
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp41
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h54
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.cpp72
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.h66
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp48
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h72
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp83
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.h78
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp995
-rw-r--r--intern/audaspace/intern/AUD_Space.h257
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp76
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h71
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp348
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.cpp128
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.h104
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp52
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h76
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp171
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h128
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileWriter.cpp139
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileWriter.h86
-rw-r--r--source/blender/blenkernel/BKE_sound.h8
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/nla.c2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2
-rw-r--r--source/blender/blenkernel/intern/sound.c31
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c4
-rw-r--r--source/blender/editors/interface/resources.c3
-rw-r--r--source/blender/editors/sound/CMakeLists.txt2
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_graph/graph_edit.c2
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c2
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c26
-rw-r--r--source/blender/quicktime/CMakeLists.txt2
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m2
-rw-r--r--source/blender/windowmanager/CMakeLists.txt2
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c8
-rw-r--r--source/blenderplayer/CMakeLists.txt8
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/CMakeLists.txt2
-rw-r--r--source/gameengine/Converter/CMakeLists.txt2
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp2
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp2
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt2
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h4
530 files changed, 39354 insertions, 23891 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3adf5825fa4..d6ca99e178d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -392,10 +392,14 @@ if(UNIX AND NOT APPLE)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
-if(WITH_PYTHON_INSTALL)
- option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
+if(WITH_PYTHON_INSTALL OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
set(PYTHON_NUMPY_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'numpy' module")
mark_as_advanced(PYTHON_NUMPY_PATH)
+ set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
+ mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
+endif()
+if(WITH_PYTHON_INSTALL)
+ option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
if(UNIX AND NOT APPLE)
option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
@@ -700,30 +704,9 @@ TEST_SHARED_PTR_SUPPORT()
TEST_UNORDERED_MAP_SUPPORT()
if(WITH_AUDASPACE)
- if(WITH_SYSTEM_AUDASPACE)
- set(AUDASPACE_DEFINITIONS
- -DWITH_AUDASPACE
- -DWITH_SYSTEM_AUDASPACE
- "-DAUD_DEVICE_H=<AUD_Device.h>"
- "-DAUD_SPECIAL_H=<AUD_Special.h>"
- "-DAUD_SOUND_H=<AUD_Sound.h>"
- "-DAUD_HANDLE_H=<AUD_Handle.h>"
- "-DAUD_SEQUENCE_H=<AUD_Sequence.h>"
- "-DAUD_TYPES_H=<AUD_Types.h>"
- "-DAUD_PYTHON_H=<python/PyAPI.h>"
- )
- else()
- set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
- set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
- set(AUDASPACE_DEFINITIONS
- -DWITH_AUDASPACE
- "-DAUD_DEVICE_H=<AUD_C-API.h>"
- "-DAUD_SPECIAL_H=<AUD_C-API.h>"
- "-DAUD_SOUND_H=<AUD_C-API.h>"
- "-DAUD_HANDLE_H=<AUD_C-API.h>"
- "-DAUD_SEQUENCE_H=<AUD_C-API.h>"
- "-DAUD_TYPES_H=<AUD_Space.h>"
- )
+ if(NOT WITH_SYSTEM_AUDASPACE)
+ set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings/C" "${CMAKE_BINARY_DIR}/extern/audaspace")
+ set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings")
endif()
endif()
@@ -1469,10 +1452,15 @@ if(WITH_PYTHON)
)
endif()
- if(WIN32 OR APPLE)
+ if(WIN32)
# pass, we have this in an archive to extract
- elseif(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
- find_python_package(numpy)
+ elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
+ if(("${PYTHON_NUMPY_PATH}" STREQUAL "") OR (${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
+ find_python_package(numpy)
+ unset(PYTHON_NUMPY_INCLUDE_DIRS CACHE)
+ set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
+ mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
+ endif()
endif()
if(WIN32 OR APPLE)
diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake
index 13368c05fbe..fb8d0d98e0e 100644
--- a/build_files/build_environment/cmake/sndfile.cmake
+++ b/build_files/build_environment/cmake/sndfile.cmake
@@ -16,19 +16,19 @@
#
# ***** END GPL LICENSE BLOCK *****
-set(SNDFILE_EXTRA_ARGS)
-set(SNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR})
+set(LIBSNDFILE_EXTRA_ARGS)
+set(LIBSNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR})
if(WIN32)
- set(SNDFILE_ENV set ${SNDFILE_ENV} &&)
+ set(LIBSNDFILE_ENV set ${LIBSNDFILE_ENV} &&)
endif()
ExternalProject_Add(external_sndfile
- URL ${SNDFILE_URI}
+ URL ${LIBSNDFILE_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
- URL_HASH MD5=${SNDFILE_HASH}
+ URL_HASH MD5=${LIBSNDFILE_HASH}
PREFIX ${BUILD_DIR}/sndfile
- CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${SNDFILE_ENV} ${CONFIGURE_COMMAND} --enable-static --disable-shared --prefix=${mingw_LIBDIR}/sndfile
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${LIBSNDFILE_ENV} ${CONFIGURE_COMMAND} --enable-static --disable-shared --prefix=${mingw_LIBDIR}/sndfile
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make install
INSTALL_DIR ${LIBDIR}/sndfile
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
index f9f9fdcface..fe60e04ee43 100644
--- a/build_files/build_environment/cmake/versions.cmake
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -216,9 +216,9 @@ set(LAPACK_VERSION 3.6.0)
set(LAPACK_URI http://www.netlib.org/lapack/lapack-${LAPACK_VERSION}.tgz)
set(LAPACK_HASH f2f6c67134e851fe189bb3ca1fbb5101)
-set(SNDFILE_VERSION 1.0.26)
-set(SNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${SNDFILE_VERSION}.tar.gz)
-set(SNDFILE_HASH ec810a0c60c08772a8a5552704b63393)
+set(LIBSNDFILE_VERSION 1.0.26)
+set(LIBSNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${LIBSNDFILE_VERSION}.tar.gz)
+set(LIBSNDFILE_HASH ec810a0c60c08772a8a5552704b63393)
#set(HIDAPI_VERSION 0.8.0-rc1)
#set(HIDAPI_URI https://github.com/signal11/hidapi/archive/hidapi-${HIDAPI_VERSION}.tar.gz)
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 9f293b9e9e3..28eaa70711c 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -2673,10 +2673,10 @@ install_DEB() {
install_packages_DEB $_packages
PRINT""
- SNDFILE_DEV="libsndfile1-dev"
- check_package_DEB $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile1-dev"
+ check_package_DEB $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_DEB $SNDFILE_DEV
+ install_packages_DEB $LIBSNDFILE_DEV
fi
PRINT ""
@@ -3271,10 +3271,10 @@ install_RPM() {
fi
PRINT""
- SNDFILE_DEV="libsndfile-devel"
- check_package_RPM $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile-devel"
+ check_package_RPM $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_RPM $SNDFILE_DEV
+ install_packages_RPM $LIBSNDFILE_DEV
fi
if [ "$WITH_ALL" = true ]; then
@@ -3678,10 +3678,10 @@ install_ARCH() {
install_packages_ARCH $_packages
PRINT""
- SNDFILE_DEV="libsndfile"
- check_package_ARCH $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile"
+ check_package_ARCH $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_ARCH $SNDFILE_DEV
+ install_packages_ARCH $LIBSNDFILE_DEV
fi
PRINT ""
diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake
index 56f18967300..4fc6496728c 100644
--- a/build_files/buildbot/config/blender_linux.cmake
+++ b/build_files/buildbot/config/blender_linux.cmake
@@ -70,11 +70,11 @@ set(FFMPEG_LIBRARIES
)
# SndFile libraries
-set(SNDFILE_LIBRARY "/usr/lib/libsndfile.a;/usr/lib/libFLAC.a" CACHE STRING "" FORCE)
+set(LIBSNDFILE_LIBRARY "/usr/lib/libsndfile.a;/usr/lib/libFLAC.a" CACHE STRING "" FORCE)
# OpenAL libraries
set(OPENAL_ROOT_DIR "/opt/lib/openal" CACHE STRING "" FORCE)
-set(OPENAL_INCLUDE_DIR "${OPENAL_ROOT_DIR}/include" CACHE STRING "" FORCE)
+set(OPENAL_INCLUDE_DIR "${OPENAL_ROOT_DIR}/include/AL" CACHE STRING "" FORCE)
set(OPENAL_LIBRARY
${OPENAL_ROOT_DIR}/lib/libopenal.a
${OPENAL_ROOT_DIR}/lib/libcommon.a
diff --git a/build_files/cmake/Modules/FindSndFile.cmake b/build_files/cmake/Modules/FindSndFile.cmake
index 1b685eacfbd..dd1f560e61f 100644
--- a/build_files/cmake/Modules/FindSndFile.cmake
+++ b/build_files/cmake/Modules/FindSndFile.cmake
@@ -1,15 +1,15 @@
# - Find SndFile library
# Find the native SndFile includes and library
# This module defines
-# SNDFILE_INCLUDE_DIRS, where to find sndfile.h, Set when
-# SNDFILE_INCLUDE_DIR is found.
-# SNDFILE_LIBRARIES, libraries to link against to use SndFile.
-# SNDFILE_ROOT_DIR, The base directory to search for SndFile.
+# LIBSNDFILE_INCLUDE_DIRS, where to find sndfile.h, Set when
+# LIBSNDFILE_INCLUDE_DIR is found.
+# LIBSNDFILE_LIBRARIES, libraries to link against to use SndFile.
+# LIBSNDFILE_ROOT_DIR, The base directory to search for SndFile.
# This can also be an environment variable.
-# SNDFILE_FOUND, If false, do not try to use SndFile.
+# LIBSNDFILE_FOUND, If false, do not try to use SndFile.
#
# also defined, but not for general use are
-# SNDFILE_LIBRARY, where to find the SndFile library.
+# LIBSNDFILE_LIBRARY, where to find the SndFile library.
#=============================================================================
# Copyright 2011 Blender Foundation.
@@ -22,27 +22,27 @@
# See the License for more information.
#=============================================================================
-# If SNDFILE_ROOT_DIR was defined in the environment, use it.
-IF(NOT SNDFILE_ROOT_DIR AND NOT $ENV{SNDFILE_ROOT_DIR} STREQUAL "")
- SET(SNDFILE_ROOT_DIR $ENV{SNDFILE_ROOT_DIR})
+# If LIBSNDFILE_ROOT_DIR was defined in the environment, use it.
+IF(NOT LIBSNDFILE_ROOT_DIR AND NOT $ENV{LIBSNDFILE_ROOT_DIR} STREQUAL "")
+ SET(LIBSNDFILE_ROOT_DIR $ENV{LIBSNDFILE_ROOT_DIR})
ENDIF()
SET(_sndfile_SEARCH_DIRS
- ${SNDFILE_ROOT_DIR}
+ ${LIBSNDFILE_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
-FIND_PATH(SNDFILE_INCLUDE_DIR sndfile.h
+FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h
HINTS
${_sndfile_SEARCH_DIRS}
PATH_SUFFIXES
include
)
-FIND_LIBRARY(SNDFILE_LIBRARY
+FIND_LIBRARY(LIBSNDFILE_LIBRARY
NAMES
sndfile
HINTS
@@ -51,18 +51,18 @@ FIND_LIBRARY(SNDFILE_LIBRARY
lib64 lib
)
-# handle the QUIETLY and REQUIRED arguments and set SNDFILE_FOUND to TRUE if
+# handle the QUIETLY and REQUIRED arguments and set LIBSNDFILE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SndFile DEFAULT_MSG
- SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
+ LIBSNDFILE_LIBRARY LIBSNDFILE_INCLUDE_DIR)
-IF(SNDFILE_FOUND)
- SET(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY})
- SET(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR})
-ENDIF(SNDFILE_FOUND)
+IF(LIBSNDFILE_FOUND)
+ SET(LIBSNDFILE_LIBRARIES ${LIBSNDFILE_LIBRARY})
+ SET(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE_INCLUDE_DIR})
+ENDIF(LIBSNDFILE_FOUND)
MARK_AS_ADVANCED(
- SNDFILE_INCLUDE_DIR
- SNDFILE_LIBRARY
+ LIBSNDFILE_INCLUDE_DIR
+ LIBSNDFILE_LIBRARY
)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 10d9ed041ef..9811116b0a7 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -318,7 +318,7 @@ function(SETUP_LIBDIRS)
link_directories(${JACK_LIBPATH})
endif()
if(WITH_CODEC_SNDFILE)
- link_directories(${SNDFILE_LIBPATH})
+ link_directories(${LIBSNDFILE_LIBPATH})
endif()
if(WITH_FFTW3)
link_directories(${FFTW3_LIBPATH})
@@ -398,7 +398,7 @@ function(setup_liblinks
target_link_libraries(${target} ${JACK_LIBRARIES})
endif()
if(WITH_CODEC_SNDFILE)
- target_link_libraries(${target} ${SNDFILE_LIBRARIES})
+ target_link_libraries(${target} ${LIBSNDFILE_LIBRARIES})
endif()
if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
target_link_libraries(${target} ${SDL_LIBRARY})
@@ -549,6 +549,12 @@ function(SETUP_BLENDER_SORTED_LIBS)
endif()
endif()
+ if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ list(APPEND BLENDER_LINK_LIBS
+ audaspace
+ audaspace-py)
+ endif()
+
# Sort libraries
set(BLENDER_SORTED_LIBS
bf_windowmanager
@@ -655,6 +661,8 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_blenfont
bf_blentranslation
bf_intern_audaspace
+ audaspace
+ audaspace-py
bf_intern_mikktspace
bf_intern_dualcon
bf_intern_cycles
@@ -1510,6 +1518,7 @@ function(find_python_package
NAMES
${package}
HINTS
+ "${PYTHON_LIBPATH}/"
"${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
"${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
PATH_SUFFIXES
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index 17118e4672a..e26466cc6d5 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -46,7 +46,7 @@ if(WITH_OPENAL)
find_package(OpenAL)
if(OPENAL_FOUND)
set(WITH_OPENAL ON)
- set(OPENAL_INCLUDE_DIR "${LIBDIR}/openal/include")
+ set(OPENAL_INCLUDE_DIR "${LIBDIR}/openal/include/AL")
else()
set(WITH_OPENAL OFF)
endif()
@@ -82,10 +82,10 @@ if(WITH_JACK)
endif()
if(WITH_CODEC_SNDFILE)
- set(SNDFILE ${LIBDIR}/sndfile)
- set(SNDFILE_INCLUDE_DIRS ${SNDFILE}/include)
- set(SNDFILE_LIBRARIES sndfile FLAC ogg vorbis vorbisenc)
- set(SNDFILE_LIBPATH ${SNDFILE}/lib ${LIBDIR}/ffmpeg/lib) # TODO, deprecate
+ set(LIBSNDFILE ${LIBDIR}/sndfile)
+ set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE}/include)
+ set(LIBSNDFILE_LIBRARIES sndfile FLAC ogg vorbis vorbisenc)
+ set(LIBSNDFILE_LIBPATH ${LIBSNDFILE}/lib ${LIBDIR}/ffmpeg/lib) # TODO, deprecate
endif()
if(WITH_PYTHON)
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index 62e0caa7c43..d5875e9cd7f 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -135,7 +135,7 @@ endif()
# Codecs
if(WITH_CODEC_SNDFILE)
find_package_wrapper(SndFile)
- if(NOT SNDFILE_FOUND)
+ if(NOT LIBSNDFILE_FOUND)
set(WITH_CODEC_SNDFILE OFF)
endif()
endif()
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 2f5d41dac32..4d2342e490e 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -36,7 +36,7 @@ set(WINTAB_INC ${LIBDIR}/wintab/include)
if(WITH_OPENAL)
set(OPENAL ${LIBDIR}/openal)
set(OPENALDIR ${LIBDIR}/openal)
- set(OPENAL_INCLUDE_DIR ${OPENAL}/include)
+ set(OPENAL_INCLUDE_DIR ${OPENAL}/include/AL)
if(MSVC)
set(OPENAL_LIBRARY openal32)
else()
@@ -46,10 +46,10 @@ if(WITH_OPENAL)
endif()
if(WITH_CODEC_SNDFILE)
- set(SNDFILE ${LIBDIR}/sndfile)
- set(SNDFILE_INCLUDE_DIRS ${SNDFILE}/include)
- set(SNDFILE_LIBRARIES libsndfile-1)
- set(SNDFILE_LIBPATH ${SNDFILE}/lib) # TODO, deprecate
+ set(LIBSNDFILE ${LIBDIR}/sndfile)
+ set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE}/include)
+ set(LIBSNDFILE_LIBRARIES libsndfile-1)
+ set(LIBSNDFILE_LIBPATH ${LIBSNDFILE}/lib) # TODO, deprecate
endif()
if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index f7e98525b8b..0e4853ee458 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -113,3 +113,8 @@ endif()
if(WITH_SDL AND WITH_SDL_DYNLOAD)
add_subdirectory(sdlew)
endif()
+
+if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ set(AUDASPACE_CMAKE_CFG ${CMAKE_CURRENT_SOURCE_DIR}/audaspace/blender_config.cmake)
+ add_subdirectory(audaspace)
+endif()
diff --git a/extern/audaspace/AUTHORS b/extern/audaspace/AUTHORS
new file mode 100644
index 00000000000..08007912102
--- /dev/null
+++ b/extern/audaspace/AUTHORS
@@ -0,0 +1,16 @@
+Main author: Jörg Müller <nexyon@gmail.com>
+
+Minor improvements have been done while audaspace was an internal part of Blender by
+
+- Campbell Barton (bug fixes and cleanup)
+- Brecht Van Lommel (bug fixes and cleanup)
+- Sergey Sharybin (bug fixes and cleanup)
+- Nathan Letwory (bug fixes and cleanup)
+- Peter Schlaile (ffmpeg)
+- Jens Verwiebe (jack on Apple)
+
+The first three of them were employed by the Blender Foundation during that time.
+
+Some features (random sounds, dynamic music, playback manager, convolution and HRTFs support) were added as part of the VALS (Virtual Alliances for Learning Society) project by
+
+- Juan Francisco Crespo Galán <dethon_5@outlook.com>
diff --git a/extern/audaspace/CHANGES b/extern/audaspace/CHANGES
new file mode 100644
index 00000000000..bd5acaa88fb
--- /dev/null
+++ b/extern/audaspace/CHANGES
@@ -0,0 +1,115 @@
+Audaspace 1.3
+=============
+
+- New features:
+ - linear interpolation for volume changes in the software mixer
+ - dynamic Loading for JACK
+- Bug fixes:
+ - renamed Jack to JACK
+ - C API was not working
+ - filter python API parameter check
+ - finding ffmpeg with pkgconfig
+
+64884a7 Windows fixes.
+53ba3e6 Implemented JACK dynamic loading.
+5ee0ee1 Continues last commit.
+c24b384 Trying to fix travis-ci python versioning once and for all (at least for python3).
+1fbf3bf Rename Jack => JACK where possible.
+6e4b31f Implemented linear interpolation for volume changes in the software mixer.
+817043c Fixing C API not working.
+c384daf Maybe travis-ci works now.
+aa7ddd7 Fix (hopefully) for previous commit.
+57c5dd7 Configure MACOSX_DEPLOYMENT_TARGET for travis-ci.
+7ae6ff9 Fix travis-ci python path.
+552fea4 Added posibillity to use math constants on MinGW
+c18ed59 Bugfix: incorrect parameter check in python API.
+6f048c3 CMake: fix finding ffmpeg with pkgconfig.
+
+Audaspace 1.2
+=============
+
+- New features:
+ - sound list
+ - random sounds
+ - dynamic music playing
+ - playback manager
+ - convolution/reverbation
+ - multi-threading
+ - binaural audio
+- API changes:
+ - changing default sample rate from 44.1 to 48 kHz
+- Bug fixes:
+ - several standard library fixes.
+- Bindings API:
+ - mixdown C API refactored
+- CMake/Building:
+ - assuring numpy is installed
+ - building the Python module on Mac OS X with CMake
+
+a6b6e70 Changing default sample rate from 44.1 to 48 kHz.
+20f0164 Bugfix: CMake custom command for python module on OS X.
+98679a2 Bugfix: using standard library (s)rand.
+5ab4fe7 Bugfix: first step in fixing the vector of array problem.
+e83f01d FFTW: trying to use complex to circumvent vector of array problem.
+093ebc0 Bugfix: abs -> std::fabs.
+328d7cc Bugfix: standard library include and call fixes.
+f78e330 Bugfix: using correct includes.
+64d7825 Behavior change: C API Mixdown
+749896b Merge pull request #3 from DethonUSAL/master
+6e9491c CMake: finding NumPy.
+
+Audaspace 1.1
+=============
+
+- Bug fixes:
+ - pkgconfig uses cmake configured library directory
+ - FFMPEG file writing crashed, also corrected pts for encoding
+ - silenced Doxygen warnings about undefined defines
+- C++ API:
+ - ResampleReader uses specs instead of sample rate
+- Bindings API:
+ - writing sounds to files
+ - reading sound data, specs and length
+ - resampling sounds
+- CMake/Building:
+ - first steps towards building for Mac
+ - windows builds copy dlls automatically
+- Python module:
+ - using distutils instead of setuptools
+ - added numpy as dependency
+- Documentation:
+ - added windows building and plugin documentation
+ - disabled html timestamps in doxygen
+ - updated sphinx template
+ - build binding documentation without installing the python module
+
+Detailed list of changes:
+
+326a300 Documentation: windows, dll copying now done automatically.
+54cac4f Windows: install dlls.
+65c2d78 Bindings: Sound length and specs properties.
+c38da70 Bindings API: adding resampling.
+374822f Documentation: Added windows and plugin documentation.
+a9dc5b9 Python module: add numpy as dependency.
+c933a02 C API: implement new API based on the python API.
+ac54c52 Python API: silence numpy warnings.
+c9491bb Python API: checking for a positive sample rate.
+4eb1fa8 Python API: reorder functions.
+ec7c00b Sphinx update and fixes.
+e16d979 FFMPEG: correct pts during encoding.
+7ab3935 Documentation: git path fix.
+28d77bb Python: use distutils directly instead of setuptools.
+1f43284 Silence doxygen warning about undefined defines.
+0d52458 CMake: improvements and fixes for building on Mac.
+37daedf FFMPEG: bugfixes for file writing.
+780ca2a ResampleReader API change
+4d9863d Python API: Optimization for cached sounds' data access.
+ea04fee Python API: read sound data and create sound buffers as well as getting the specs of a sound.
+335b293 Python sound writing API.
+36a7252 Pkgconfig: use cmake configured library directory.
+5503908 Doxygen: disable html timestamps.
+
+Initial Release of Audaspace 1.0
+================================
+
+Audaspace has been the internal audio library of blender since blender 2.5. It is now released as a standalone library to be used in other projects as well.
diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt
new file mode 100644
index 00000000000..ad856fd8743
--- /dev/null
+++ b/extern/audaspace/CMakeLists.txt
@@ -0,0 +1,983 @@
+################################################################################
+# Copyright 2009-2016 Jörg Müller
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+################################################################################
+
+cmake_minimum_required(VERSION 3.1)
+include(CMakeDependentOption)
+
+if(POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW)
+endif()
+
+project(audaspace)
+
+set(AUDASPACE_VERSION 1.3)
+set(AUDASPACE_LONG_VERSION ${AUDASPACE_VERSION}.0)
+
+if(DEFINED AUDASPACE_CMAKE_CFG)
+ include(${AUDASPACE_CMAKE_CFG})
+endif()
+
+if(NOT DEFINED AUDASPACE_STANDALONE)
+ set(AUDASPACE_STANDALONE TRUE)
+endif()
+
+# sources
+
+set(SRC
+ src/devices/DefaultSynchronizer.cpp
+ src/devices/DeviceManager.cpp
+ src/devices/NULLDevice.cpp
+ src/devices/ReadDevice.cpp
+ src/devices/SoftwareDevice.cpp
+ src/Exception.cpp
+ src/file/File.cpp
+ src/file/FileManager.cpp
+ src/file/FileWriter.cpp
+ src/fx/Accumulator.cpp
+ src/fx/ADSR.cpp
+ src/fx/ADSRReader.cpp
+ src/fx/BaseIIRFilterReader.cpp
+ src/fx/ButterworthCalculator.cpp
+ src/fx/Butterworth.cpp
+ src/fx/CallbackIIRFilterReader.cpp
+ src/fx/Delay.cpp
+ src/fx/DelayReader.cpp
+ src/fx/DynamicIIRFilter.cpp
+ src/fx/DynamicIIRFilterReader.cpp
+ src/fx/DynamicMusic.cpp
+ src/fx/Effect.cpp
+ src/fx/EffectReader.cpp
+ src/fx/Envelope.cpp
+ src/fx/Fader.cpp
+ src/fx/FaderReader.cpp
+ src/fx/HighpassCalculator.cpp
+ src/fx/Highpass.cpp
+ src/fx/IIRFilter.cpp
+ src/fx/IIRFilterReader.cpp
+ src/fx/Limiter.cpp
+ src/fx/LimiterReader.cpp
+ src/fx/Loop.cpp
+ src/fx/LoopReader.cpp
+ src/fx/LowpassCalculator.cpp
+ src/fx/Lowpass.cpp
+ src/fx/MutableReader.cpp
+ src/fx/MutableSound.cpp
+ src/fx/Pitch.cpp
+ src/fx/PitchReader.cpp
+ src/fx/PlaybackManager.cpp
+ src/fx/PlaybackCategory.cpp
+ src/fx/Reverse.cpp
+ src/fx/ReverseReader.cpp
+ src/fx/SoundList.cpp
+ src/fx/Source.cpp
+ src/fx/Sum.cpp
+ src/fx/Threshold.cpp
+ src/fx/Volume.cpp
+ src/fx/VolumeReader.cpp
+ src/fx/VolumeSound.cpp
+ src/fx/VolumeStorage.cpp
+ src/generator/Sawtooth.cpp
+ src/generator/SawtoothReader.cpp
+ src/generator/Silence.cpp
+ src/generator/SilenceReader.cpp
+ src/generator/Sine.cpp
+ src/generator/SineReader.cpp
+ src/generator/Square.cpp
+ src/generator/SquareReader.cpp
+ src/generator/Triangle.cpp
+ src/generator/TriangleReader.cpp
+ src/respec/ChannelMapper.cpp
+ src/respec/ChannelMapperReader.cpp
+ src/respec/Converter.cpp
+ src/respec/ConverterFunctions.cpp
+ src/respec/ConverterReader.cpp
+ src/respec/JOSResample.cpp
+ src/respec/JOSResampleReaderCoeff.cpp
+ src/respec/JOSResampleReader.cpp
+ src/respec/LinearResample.cpp
+ src/respec/LinearResampleReader.cpp
+ src/respec/Mixer.cpp
+ src/respec/ResampleReader.cpp
+ src/respec/SpecsChanger.cpp
+ src/sequence/AnimateableProperty.cpp
+ src/sequence/Double.cpp
+ src/sequence/DoubleReader.cpp
+ src/sequence/PingPong.cpp
+ src/sequence/Sequence.cpp
+ src/sequence/SequenceData.cpp
+ src/sequence/SequenceEntry.cpp
+ src/sequence/SequenceHandle.cpp
+ src/sequence/SequenceReader.cpp
+ src/sequence/Superpose.cpp
+ src/sequence/SuperposeReader.cpp
+ src/util/Barrier.cpp
+ src/util/Buffer.cpp
+ src/util/BufferReader.cpp
+ src/util/StreamBuffer.cpp
+ src/util/ThreadPool.cpp
+)
+
+set(PRIVATE_HDR
+ src/sequence/SequenceHandle.h
+)
+
+set(PUBLIC_HDR
+ include/devices/DefaultSynchronizer.h
+ include/devices/DeviceManager.h
+ include/devices/I3DDevice.h
+ include/devices/I3DHandle.h
+ include/devices/IDeviceFactory.h
+ include/devices/IDevice.h
+ include/devices/IHandle.h
+ include/devices/ISynchronizer.h
+ include/devices/NULLDevice.h
+ include/devices/ReadDevice.h
+ include/devices/SoftwareDevice.h
+ include/Exception.h
+ include/file/File.h
+ include/file/FileManager.h
+ include/file/FileWriter.h
+ include/file/IFileInput.h
+ include/file/IFileOutput.h
+ include/file/IWriter.h
+ include/fx/Accumulator.h
+ include/fx/ADSR.h
+ include/fx/ADSRReader.h
+ include/fx/BaseIIRFilterReader.h
+ include/fx/ButterworthCalculator.h
+ include/fx/Butterworth.h
+ include/fx/CallbackIIRFilterReader.h
+ include/fx/Delay.h
+ include/fx/DelayReader.h
+ include/fx/DynamicIIRFilter.h
+ include/fx/DynamicIIRFilterReader.h
+ include/fx/DynamicMusic.h
+ include/fx/Effect.h
+ include/fx/EffectReader.h
+ include/fx/Envelope.h
+ include/fx/Fader.h
+ include/fx/FaderReader.h
+ include/fx/HighpassCalculator.h
+ include/fx/Highpass.h
+ include/fx/IDynamicIIRFilterCalculator.h
+ include/fx/IIRFilter.h
+ include/fx/IIRFilterReader.h
+ include/fx/Limiter.h
+ include/fx/LimiterReader.h
+ include/fx/Loop.h
+ include/fx/LoopReader.h
+ include/fx/LowpassCalculator.h
+ include/fx/Lowpass.h
+ include/fx/MutableReader.h
+ include/fx/MutableSound.h
+ include/fx/Pitch.h
+ include/fx/PitchReader.h
+ include/fx/PlaybackManager.h
+ include/fx/PlaybackCategory.h
+ include/fx/Reverse.h
+ include/fx/ReverseReader.h
+ include/fx/SoundList.h
+ include/fx/Source.h
+ include/fx/Sum.h
+ include/fx/Threshold.h
+ include/fx/Volume.h
+ include/fx/VolumeReader.h
+ include/fx/VolumeSound.h
+ include/fx/VolumeStorage.h
+ include/generator/Sawtooth.h
+ include/generator/SawtoothReader.h
+ include/generator/Silence.h
+ include/generator/SilenceReader.h
+ include/generator/Sine.h
+ include/generator/SineReader.h
+ include/generator/Square.h
+ include/generator/SquareReader.h
+ include/generator/Triangle.h
+ include/generator/TriangleReader.h
+ include/IReader.h
+ include/ISound.h
+ include/plugin/PluginManager.h
+ include/respec/ChannelMapper.h
+ include/respec/ChannelMapperReader.h
+ include/respec/ConverterFunctions.h
+ include/respec/Converter.h
+ include/respec/ConverterReader.h
+ include/respec/JOSResample.h
+ include/respec/JOSResampleReader.h
+ include/respec/LinearResample.h
+ include/respec/LinearResampleReader.h
+ include/respec/Mixer.h
+ include/respec/ResampleReader.h
+ include/respec/Specification.h
+ include/respec/SpecsChanger.h
+ include/sequence/AnimateableProperty.h
+ include/sequence/Double.h
+ include/sequence/DoubleReader.h
+ include/sequence/PingPong.h
+ include/sequence/SequenceData.h
+ include/sequence/SequenceEntry.h
+ include/sequence/Sequence.h
+ include/sequence/SequenceReader.h
+ include/sequence/Superpose.h
+ include/sequence/SuperposeReader.h
+ include/util/Barrier.h
+ include/util/Buffer.h
+ include/util/BufferReader.h
+ include/util/ILockable.h
+ include/util/Math3D.h
+ include/util/StreamBuffer.h
+ include/util/ThreadPool.h
+)
+
+set(HDR ${PRIVATE_HDR} ${PUBLIC_HDR})
+
+set(INCLUDE ${CMAKE_CURRENT_BINARY_DIR} include)
+
+if(WIN32)
+ set(LIBRARIES)
+ if(AUDASPACE_STANDALONE)
+ set(DLLS)
+ set(LIBRARY_PATH "../lib" CACHE PATH "Path which contains the libraries.")
+ file(GLOB LIBRARY_DIRS ${LIBRARY_PATH}/*)
+ list(APPEND CMAKE_PREFIX_PATH ${LIBRARY_DIRS})
+ endif()
+else()
+ set(LIBRARIES ${CMAKE_DL_LIBS} -lpthread)
+endif()
+
+set(STATIC_PLUGINS "")
+
+# dependencies
+
+if(AUDASPACE_STANDALONE)
+ set(PACKAGE_OPTION QUIET)
+ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
+
+ option(BUILD_DEMOS "Build and install demos" TRUE)
+
+ option(SHARED_LIBRARY "Build Shared Library" TRUE)
+
+ option(WITH_C "Build C Module" TRUE)
+ option(WITH_DOCS "Build C++ HTML Documentation with Doxygen" TRUE)
+ option(WITH_FFMPEG "Build With FFMPEG" TRUE)
+ option(WITH_FFTW "Build With FFTW" TRUE)
+ option(WITH_JACK "Build With Plugin" TRUE)
+ option(WITH_LIBSNDFILE "Build With LibSndFile" TRUE)
+ option(WITH_OPENAL "Build With OpenAL" TRUE)
+ option(WITH_PYTHON "Build With Python Library" TRUE)
+ option(WITH_SDL "Build With SDL" TRUE)
+ option(WITH_STRICT_DEPENDENCIES "Error and abort instead of warning if a library is not found." FALSE)
+
+ if(WITH_STRICT_DEPENDENCIES)
+ set(PACKAGE_OPTION REQUIRED)
+ endif()
+endif()
+
+if(WIN32)
+ set(DEFAULT_PLUGIN_PATH "." CACHE STRING "Default plugin installation and loading path.")
+ set(DOCUMENTATION_INSTALL_PATH "doc" CACHE PATH "Path where the documentation is installed.")
+else()
+ set(DEFAULT_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/share/audaspace/plugins" CACHE STRING "Default plugin installation and loading path.")
+ set(DOCUMENTATION_INSTALL_PATH "share/doc/audaspace" CACHE PATH "Path where the documentation is installed.")
+endif()
+
+if(AUDASPACE_STANDALONE)
+ cmake_dependent_option(SEPARATE_C "Build C Binding as separate library" TRUE "WITH_C" FALSE)
+ cmake_dependent_option(PLUGIN_FFMPEG "Build FFMPEG Plugin" TRUE "WITH_FFMPEG;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_JACK "Build JACK Plugin" TRUE "WITH_JACK;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_LIBSNDFILE "Build LibSndFile Plugin" TRUE "WITH_LIBSNDFILE;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_OPENAL "Build OpenAL Plugin" TRUE "WITH_OPENAL;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_SDL "Build SDL Plugin" TRUE "WITH_SDL;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(WITH_PYTHON_MODULE "Build Python Module" TRUE "WITH_PYTHON" FALSE)
+ cmake_dependent_option(USE_SDL2 "Use SDL2 instead of 1 if available" TRUE "WITH_SDL" FALSE)
+ cmake_dependent_option(DYNLOAD_JACK "Dynamically load JACK" FALSE "WITH_JACK" FALSE)
+ cmake_dependent_option(WITH_BINDING_DOCS "Build C/Python HTML Documentation with Sphinx" TRUE "WITH_PYTHON_MODULE" FALSE)
+endif()
+
+# compiler options
+
+set(CMAKE_CXX_STANDARD 11)
+
+if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ list(APPEND CMAKE_C_COMPILER_FLAGS "-fvisibility=hidden")
+ list(APPEND CMAKE_CXX_COMPILER_FLAGS "-fvisibility=hidden")
+endif()
+
+if(MSVC)
+ if(AUDASPACE_STANDALONE)
+ list(APPEND CMAKE_C_FLAGS_DEBUG "/Zi /Od")
+ list(APPEND CMAKE_CXX_FLAGS_DEBUG "/Zi /Od")
+ list(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG "/DEBUG")
+ list(APPEND CMAKE_STATIC_LINKER_FLAGS_DEBUG "/DEBUG")
+ list(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG")
+ endif()
+ add_definitions(
+ /D_USE_MATH_DEFINES
+ /EHsc
+ /DNOMINMAX
+ /D_STDINT_H
+ )
+ if(SHARED_LIBRARY)
+ include(GenerateExportHeader)
+ endif()
+endif()
+
+if(APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
+endif()
+
+# platform specific options
+
+if(MSYS OR MINGW)
+ add_definitions(-D_USE_MATH_DEFINES)
+endif()
+
+# C
+if(WITH_C)
+ set(C_SRC
+ bindings/C/AUD_ThreadPool.cpp
+ bindings/C/AUD_Source.cpp
+ bindings/C/AUD_Device.cpp
+ bindings/C/AUD_DynamicMusic.cpp
+ bindings/C/AUD_Handle.cpp
+ bindings/C/AUD_PlaybackManager.cpp
+ bindings/C/AUD_Sequence.cpp
+ bindings/C/AUD_Sound.cpp
+ bindings/C/AUD_Special.cpp
+ )
+ set(C_HDR
+ bindings/C/AUD_ThreadPool.h
+ bindings/C/AUD_Source.h
+ bindings/C/AUD_Device.h
+ bindings/C/AUD_DynamicMusic.h
+ bindings/C/AUD_Handle.h
+ bindings/C/AUD_PlaybackManager.h
+ bindings/C/AUD_Sequence.h
+ bindings/C/AUD_Sound.h
+ bindings/C/AUD_Special.h
+ bindings/C/AUD_Types.h
+ )
+
+if(WITH_FFTW)
+ list(APPEND C_SRC
+ bindings/C/AUD_HRTF.cpp
+ bindings/C/AUD_ImpulseResponse.cpp
+ )
+
+ list(APPEND C_HDR
+ bindings/C/AUD_HRTF.h
+ bindings/C/AUD_ImpulseResponse.h
+ )
+ endif()
+
+ if(NOT SEPARATE_C)
+ list(APPEND SRC ${C_SRC})
+ list(APPEND HDR ${C_HDR})
+ else()
+ set(AUDASPACE_C_LIBRARY -laudaspace-c)
+ endif()
+endif()
+
+# FFMPEG
+if(WITH_FFMPEG)
+ if(AUDASPACE_STANDALONE)
+ find_package(FFMPEG ${PACKAGE_OPTION})
+ endif()
+
+ if(FFMPEG_FOUND)
+ set(FFMPEG_SRC
+ plugins/ffmpeg/FFMPEG.cpp
+ plugins/ffmpeg/FFMPEGReader.cpp
+ plugins/ffmpeg/FFMPEGWriter.cpp
+ )
+ set(FFMPEG_HDR
+ plugins/ffmpeg/FFMPEG.h
+ plugins/ffmpeg/FFMPEGReader.h
+ plugins/ffmpeg/FFMPEGWriter.h
+ )
+
+ if(NOT PLUGIN_FFMPEG)
+ list(APPEND INCLUDE ${FFMPEG_INCLUDE_DIRS})
+ list(APPEND LIBRARIES ${FFMPEG_LIBRARIES})
+ list(APPEND SRC ${FFMPEG_SRC})
+ list(APPEND HDR ${FFMPEG_HDR})
+ list(APPEND STATIC_PLUGINS FFMPEG)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB FFMPEG_DLLS ${LIBRARY_PATH}/ffmpeg/bin/*.dll)
+ list(APPEND DLLS ${FFMPEG_DLLS})
+ endif()
+ else()
+ set(WITH_FFMPEG FALSE CACHE BOOL "Build With FFMPEG" FORCE)
+ message(WARNING "FFMPEG not found, plugin will not be built.")
+ endif()
+endif()
+
+# FFTW
+if(WITH_FFTW)
+ if(AUDASPACE_STANDALONE)
+ find_package(FFTW ${PACKAGE_OPTION})
+ endif()
+
+ if(FFTW_FOUND)
+ set(FFTW_SRC
+ src/fx/BinauralSound.cpp
+ src/fx/BinauralReader.cpp
+ src/fx/Convolver.cpp
+ src/fx/ConvolverReader.cpp
+ src/fx/ConvolverSound.cpp
+ src/fx/FFTConvolver.cpp
+ src/fx/HRTF.cpp
+ src/fx/ImpulseResponse.cpp
+ src/util/FFTPlan.cpp
+ )
+ set(FFTW_HDR
+ include/fx/BinauralSound.h
+ include/fx/BinauralReader.h
+ include/fx/Convolver.h
+ include/fx/ConvolverReader.h
+ include/fx/ConvolverSound.h
+ include/fx/FFTConvolver.h
+ include/fx/HRTF.h
+ include/fx/HRTFLoader.h
+ include/fx/ImpulseResponse.h
+ include/util/FFTPlan.h
+ )
+
+ add_definitions(-DWITH_CONVOLUTION)
+
+ list(APPEND INCLUDE ${FFTW_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${FFTW_LIBRARY})
+
+ list(APPEND SRC ${FFTW_SRC})
+ list(APPEND HDR ${FFTW_HDR})
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB FFTW_DLLS ${LIBRARY_PATH}/fftw/bin/*.dll)
+ list(APPEND DLLS ${FFTW_DLLS})
+ endif()
+ else()
+ set(WITH_FFTW FALSE CACHE BOOL "Build With FFTW" FORCE)
+ message(WARNING "FFTW not found, convolution functionality will not be built.")
+ endif()
+endif()
+
+# JACK
+if(WITH_JACK)
+ if(AUDASPACE_STANDALONE)
+ find_package(Jack ${PACKAGE_OPTION})
+ endif()
+
+ if(JACK_FOUND)
+ set(JACK_SRC
+ plugins/jack/JackDevice.cpp
+ plugins/jack/JackSynchronizer.cpp
+ plugins/jack/JackLibrary.cpp
+ )
+ set(JACK_HDR
+ plugins/jack/JackDevice.h
+ plugins/jack/JackSynchronizer.h
+ plugins/jack/JackLibrary.h
+ plugins/jack/JackSymbols.h
+ )
+
+ if(DYNLOAD_JACK)
+ add_definitions(-DDYNLOAD_JACK)
+ endif()
+
+ if(NOT PLUGIN_JACK)
+ list(APPEND INCLUDE ${JACK_INCLUDE_DIRS})
+ if(NOT DYNLOAD_JACK)
+ list(APPEND LIBRARIES ${JACK_LIBRARIES})
+ endif()
+ list(APPEND SRC ${JACK_SRC})
+ list(APPEND HDR ${JACK_HDR})
+ list(APPEND STATIC_PLUGINS JackDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB JACK_DLLS ${LIBRARY_PATH}/jack/bin/*.dll)
+ list(APPEND DLLS ${JACK_DLLS})
+ endif()
+ else()
+ set(WITH_JACK FALSE CACHE BOOL "Build With JACK" FORCE)
+ message(WARNING "JACK not found, plugin will not be built.")
+ endif()
+endif()
+
+# LibSndFile
+if(WITH_LIBSNDFILE)
+ if(AUDASPACE_STANDALONE)
+ find_package(LibSndFile ${PACKAGE_OPTION})
+ endif()
+
+ if(LIBSNDFILE_FOUND)
+ set(LIBSNDFILE_SRC
+ plugins/libsndfile/SndFile.cpp
+ plugins/libsndfile/SndFileReader.cpp
+ plugins/libsndfile/SndFileWriter.cpp
+ )
+ set(LIBSNDFILE_HDR
+ plugins/libsndfile/SndFile.h
+ plugins/libsndfile/SndFileReader.h
+ plugins/libsndfile/SndFileWriter.h
+ )
+
+ if(NOT PLUGIN_LIBSNDFILE)
+ list(APPEND INCLUDE ${LIBSNDFILE_INCLUDE_DIRS})
+ list(APPEND LIBRARIES ${LIBSNDFILE_LIBRARIES})
+ list(APPEND SRC ${LIBSNDFILE_SRC})
+ list(APPEND HDR ${LIBSNDFILE_HDR})
+ list(APPEND STATIC_PLUGINS SndFile)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB LIBSNDFILE_DLLS ${LIBRARY_PATH}/libsndfile/bin/*.dll)
+ list(APPEND DLLS ${LIBSNDFILE_DLLS})
+ endif()
+ else()
+ set(WITH_LIBSNDFILE FALSE CACHE BOOL "Build With LibSndFile" FORCE)
+ message(WARNING "LibSndFile not found, plugin will not be built.")
+ endif()
+endif()
+
+# OpenAL
+if(WITH_OPENAL)
+ if(AUDASPACE_STANDALONE)
+ find_package(OpenAL ${PACKAGE_OPTION})
+ endif()
+
+ if(OPENAL_FOUND)
+ set(OPENAL_SRC
+ plugins/openal/OpenALDevice.cpp
+ plugins/openal/OpenALReader.cpp
+ )
+ set(OPENAL_HDR
+ plugins/openal/OpenALDevice.h
+ plugins/openal/OpenALReader.h
+ )
+
+ if(NOT PLUGIN_OPENAL)
+ list(APPEND INCLUDE ${OPENAL_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${OPENAL_LIBRARY})
+ list(APPEND SRC ${OPENAL_SRC})
+ list(APPEND HDR ${OPENAL_HDR})
+ list(APPEND STATIC_PLUGINS OpenALDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB OPENAL_DLLS ${LIBRARY_PATH}/OpenAL/bin/*.dll)
+ list(APPEND DLLS ${OPENAL_DLLS})
+ endif()
+ else()
+ set(WITH_OPENAL FALSE CACHE BOOL "Build With OpenAL" FORCE)
+ message(WARNING "OpenAL not found, plugin will not be built.")
+ endif()
+endif()
+
+# Python
+if(WITH_PYTHON)
+ if(AUDASPACE_STANDALONE)
+ find_package(PythonLibs 3.2 ${PACKAGE_OPTION})
+ find_package(NumPy ${PACKAGE_OPTION})
+ endif()
+
+ if(PYTHONLIBS_FOUND AND NUMPY_FOUND)
+ list(APPEND INCLUDE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS})
+
+ if(WITH_PYTHON_MODULE)
+ find_package(PythonInterp 3.2 ${PACKAGE_OPTION})
+
+ if(NOT PYTHONINTERP_FOUND)
+ set(WITH_PYTHON_MODULE FALSE)
+ message(WARNING "Python interpreter not found, module will not be built.")
+ endif()
+ endif()
+
+ set(AUDASPACE_PY_LIBRARY -laudaspace-py)
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB PYTHON_DLLS ${LIBRARY_PATH}/Python/bin/*.dll)
+ list(APPEND DLLS ${PYTHON_DLLS})
+ endif()
+ else()
+ set(WITH_PYTHON FALSE CACHE BOOL "Build With Python Library" FORCE)
+ message(WARNING "Python libraries not found, language binding will not be built.")
+ endif()
+endif()
+
+# SDL
+if(WITH_SDL)
+ if(AUDASPACE_STANDALONE)
+ if(USE_SDL2)
+ find_package(SDL2)
+ if(SDL2_FOUND)
+ set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIR})
+ set(SDL_LIBRARY ${SDL2_LIBRARY})
+ set(SDL_FOUND TRUE)
+ else()
+ find_package(SDL ${PACKAGE_OPTION})
+ endif()
+ else()
+ find_package(SDL ${PACKAGE_OPTION})
+ endif()
+ endif()
+
+ if(SDL_FOUND)
+ set(SDL_SRC
+ plugins/sdl/SDLDevice.cpp
+ )
+ set(SDL_HDR
+ plugins/sdl/SDLDevice.h
+ )
+
+ if(NOT PLUGIN_SDL)
+ list(APPEND INCLUDE ${SDL_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${SDL_LIBRARY})
+ list(APPEND SRC ${SDL_SRC})
+ list(APPEND HDR ${SDL_HDR})
+ list(APPEND STATIC_PLUGINS SDLDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB SDL_DLLS ${LIBRARY_PATH}/sdl/bin/*.dll)
+ list(APPEND DLLS ${SDL_DLLS})
+ endif()
+ else()
+ set(WITH_SDL FALSE CACHE BOOL "Build With SDL" FORCE)
+ message(WARNING "SDL not found, plugin will not be built.")
+ endif()
+endif()
+
+# library configuration
+
+if(SHARED_LIBRARY)
+ set(AUD_LIBRARY_TYPE AUD_SHARED_LIBRARY)
+ set(LIBRARY_TYPE SHARED)
+ add_definitions(-DAUD_BUILD_SHARED_LIBRARY)
+else()
+ set(AUD_LIBRARY_TYPE AUD_STATIC_LIBRARY)
+ set(LIBRARY_TYPE STATIC)
+endif()
+
+# file configuration
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/Audaspace.h.in ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h ESCAPE_QUOTES @ONLY)
+
+list(APPEND HDR ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h)
+
+set(STATIC_PLUGIN_CLASSES "")
+set(STATIC_PLUGIN_REGISTERS "")
+
+foreach(PLUGIN ${STATIC_PLUGINS})
+ list(APPEND STATIC_PLUGIN_CLASSES "STATIC_PLUGIN_CLASS(" ${PLUGIN} ")\n")
+ list(APPEND STATIC_PLUGIN_REGISTERS "\tSTATIC_PLUGIN_REGISTER(" ${PLUGIN} ")\n")
+endforeach()
+
+string(CONCAT STATIC_PLUGIN_CLASSES ${STATIC_PLUGIN_CLASSES})
+string(CONCAT STATIC_PLUGIN_REGISTERS ${STATIC_PLUGIN_REGISTERS})
+
+if(WIN32)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin/PluginManagerWindows.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp ESCAPE_QUOTES @ONLY)
+ if(WITH_FFTW)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/fx/HRTFLoaderWindows.cpp ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp COPYONLY)
+ endif()
+else()
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin/PluginManagerUnix.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp ESCAPE_QUOTES @ONLY)
+ if(WITH_FFTW)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/fx/HRTFLoaderUnix.cpp ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp COPYONLY)
+ endif()
+endif()
+
+list(APPEND SRC ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp)
+if(WITH_FFTW)
+ list(APPEND SRC ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp)
+endif()
+
+# directories
+
+include_directories(${INCLUDE})
+link_directories()
+
+# install configuration
+
+if(WIN32)
+ set(BIN_DESTINATION ".")
+else()
+ set(BIN_DESTINATION "bin")
+endif()
+
+set(LIB_DESTINATION "lib${LIB_SUFFIX}")
+
+# library
+
+add_library(audaspace ${LIBRARY_TYPE} ${SRC} ${HDR})
+target_link_libraries(audaspace ${LIBRARIES})
+set_target_properties(audaspace PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+
+if(AUDASPACE_STANDALONE)
+ install(TARGETS audaspace
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+
+ install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/audaspace)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h DESTINATION include/audaspace)
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages/pkgconfig/audaspace.pc.in ${CMAKE_CURRENT_BINARY_DIR}/audaspace.pc @ONLY)
+
+ if(NOT WIN32 AND NOT APPLE)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/audaspace.pc DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
+ endif()
+endif()
+
+# plugins
+
+if(WITH_FFMPEG AND PLUGIN_FFMPEG)
+ add_definitions(-DFFMPEG_PLUGIN)
+ include_directories(${INCLUDE} ${FFMPEG_INCLUDE_DIRS})
+ add_library(audffmpeg SHARED ${FFMPEG_SRC} ${FFMPEG_HDR} ${HDR})
+ target_link_libraries(audffmpeg audaspace ${FFMPEG_LIBRARIES})
+ set_target_properties(audffmpeg PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audffmpeg DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_JACK AND PLUGIN_JACK)
+ add_definitions(-DJACK_PLUGIN)
+ include_directories(${INCLUDE} ${JACK_INCLUDE_DIRS})
+ add_library(audjack SHARED ${JACK_SRC} ${JACK_HDR} ${HDR})
+ if(DYNLOAD_JACK)
+ target_link_libraries(audjack audaspace)
+ else()
+ target_link_libraries(audjack audaspace ${JACK_LIBRARIES})
+ endif()
+ set_target_properties(audjack PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audjack DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_LIBSNDFILE AND PLUGIN_LIBSNDFILE)
+ add_definitions(-DLIBSNDFILE_PLUGIN)
+ include_directories(${INCLUDE} ${LIBSNDFILE_INCLUDE_DIRS})
+ add_library(audlibsndfile SHARED ${LIBSNDFILE_SRC} ${LIBSNDFILE_HDR} ${HDR})
+ set_target_properties(audlibsndfile PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audlibsndfile audaspace ${LIBSNDFILE_LIBRARIES})
+ install(TARGETS audlibsndfile DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_OPENAL AND PLUGIN_OPENAL)
+ add_definitions(-DOPENAL_PLUGIN)
+ include_directories(${INCLUDE} ${OPENAL_INCLUDE_DIR})
+ add_library(audopenal SHARED ${OPENAL_SRC} ${OPENAL_HDR} ${HDR})
+ set_target_properties(audopenal PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audopenal audaspace ${OPENAL_LIBRARY})
+ install(TARGETS audopenal DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_SDL AND PLUGIN_SDL)
+ add_definitions(-DSDL_PLUGIN)
+ include_directories(${INCLUDE} ${SDL_INCLUDE_DIR})
+ add_library(audsdl SHARED ${SDL_SRC} ${SDL_HDR} ${HDR})
+ set_target_properties(audsdl PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audsdl audaspace ${SDL_LIBRARY})
+ install(TARGETS audsdl DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+# dlls
+
+if(WIN32)
+ if(DLLS)
+ install(FILES ${DLLS} DESTINATION ${BIN_DESTINATION})
+ endif()
+endif()
+
+# demos
+
+if(BUILD_DEMOS)
+ include_directories(${INCLUDE})
+
+ set(DEMOS audaplay audaconvert audaremap signalgen randsounds dynamicmusic playbackmanager)
+
+ add_executable(audaplay demos/audaplay.cpp)
+ target_link_libraries(audaplay audaspace)
+
+ add_executable(audaconvert demos/audaconvert.cpp)
+ target_link_libraries(audaconvert audaspace)
+
+ add_executable(audaremap demos/audaremap.cpp)
+ target_link_libraries(audaremap audaspace)
+
+ add_executable(signalgen demos/signalgen.cpp)
+ target_link_libraries(signalgen audaspace)
+
+ add_executable(randsounds demos/randsounds.cpp)
+ target_link_libraries(randsounds audaspace)
+
+ add_executable(dynamicmusic demos/dynamicmusic.cpp)
+ target_link_libraries(dynamicmusic audaspace)
+
+ add_executable(playbackmanager demos/playbackmanager.cpp)
+ target_link_libraries(playbackmanager audaspace)
+
+ if(WITH_FFTW)
+ list(APPEND DEMOS convolution binaural)
+
+ add_executable(convolution demos/convolution.cpp)
+ target_link_libraries(convolution audaspace)
+
+ add_executable(binaural demos/binaural.cpp)
+ target_link_libraries(binaural audaspace)
+ endif()
+
+ if(WITH_OPENAL)
+ list(APPEND DEMOS openaldevices)
+
+ add_executable(openaldevices demos/openaldevices.cpp)
+ if(PLUGIN_OPENAL)
+ target_link_libraries(openaldevices audaspace audopenal)
+ else()
+ target_link_libraries(openaldevices audaspace)
+ endif()
+ endif()
+
+ install(TARGETS ${DEMOS}
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+endif()
+
+# bindings
+
+if(WITH_C)
+ if(SEPARATE_C)
+ add_library(audaspace-c ${LIBRARY_TYPE} ${C_SRC} ${C_HDR})
+ target_link_libraries(audaspace-c audaspace)
+ set_target_properties(audaspace-c PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audaspace-c
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+ endif()
+
+ if(AUDASPACE_STANDALONE)
+ install(FILES ${C_HDR} DESTINATION include/audaspace)
+ endif()
+endif()
+
+if(WITH_PYTHON)
+ set(PYTHON_SRC
+ bindings/python/PyAPI.cpp
+ bindings/python/PyDevice.cpp
+ bindings/python/PyDynamicMusic.cpp
+ bindings/python/PyHandle.cpp
+ bindings/python/PyPlaybackManager.cpp
+ bindings/python/PySequence.cpp
+ bindings/python/PySequenceEntry.cpp
+ bindings/python/PySound.cpp
+ bindings/python/PySource.cpp
+ bindings/python/PyThreadPool.cpp
+ )
+ set(PYTHON_HDR
+ bindings/python/PyAPI.h
+ bindings/python/PyDevice.h
+ bindings/python/PyDynamicMusic.h
+ bindings/python/PyHandle.h
+ bindings/python/PyPlaybackManager.h
+ bindings/python/PySequence.h
+ bindings/python/PySequenceEntry.h
+ bindings/python/PySound.h
+ bindings/python/PySource.h
+ bindings/python/PyThreadPool.h
+ )
+
+ if(WITH_FFTW)
+ list(APPEND PYTHON_SRC
+ bindings/python/PyHRTF.cpp
+ bindings/python/PyImpulseResponse.cpp
+ )
+ list(APPEND PYTHON_HDR
+ bindings/python/PyHRTF.h
+ bindings/python/PyImpulseResponse.h
+ )
+ endif()
+
+ add_library(audaspace-py ${LIBRARY_TYPE} ${PYTHON_SRC} ${PYTHON_HDR})
+ target_link_libraries(audaspace-py audaspace ${PYTHON_LIBRARIES})
+ set_target_properties(audaspace-py PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+
+ if(AUDASPACE_STANDALONE)
+ install(TARGETS audaspace-py
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+
+ install(FILES ${PYTHON_HDR} DESTINATION include/audaspace/python)
+ endif()
+
+ if(WITH_PYTHON_MODULE)
+ set(PYTHON_SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/python)
+ configure_file(${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py ESCAPE_QUOTES @ONLY)
+
+ if(APPLE)
+ add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ elseif(WIN32)
+ set(ENV{VS100COMNTOOLS} $ENV{VS120COMNTOOLS})
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ else()
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ endif()
+ add_custom_target(pythonmodule ALL DEPENDS build SOURCES ${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${PYTHON_SRC} ${PYTHON_HDR})
+ add_dependencies(pythonmodule audaspace)
+
+ install(CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} setup.py install --root=\$ENV{DESTDIR} --prefix=${CMAKE_INSTALL_PREFIX})")
+ endif()
+endif()
+
+# docs
+
+if(WITH_DOCS)
+ find_package(Doxygen ${PACKAGE_OPTION})
+
+ if(DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
+
+ add_custom_target(audaspace_doc ALL ${DOXYGEN_EXECUTABLE} Doxyfile COMMENT "Building C++ HTML documentation with Doxygen.")
+ else()
+ set(WITH_DOCS FALSE CACHE BOOL "Build C++ HTML Documentation with Doxygen" FORCE)
+ message(WARNING "Doxygen (and/or dot) not found, documentation will not be built.")
+ endif()
+endif()
+
+if(WITH_BINDING_DOCS)
+ find_package(Sphinx ${PACKAGE_OPTION})
+
+ if(SPHINX_FOUND)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bindings/doc/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/conf.py @ONLY)
+
+ add_custom_target(bindings_doc ALL COMMAND ${PYTHON_EXECUTABLE} setup.py --build-docs ${SPHINX_EXECUTABLE} -q -b html -c "${CMAKE_CURRENT_BINARY_DIR}" -d "${CMAKE_CURRENT_BINARY_DIR}/_doctrees" "${CMAKE_CURRENT_SOURCE_DIR}/bindings/doc" "${CMAKE_CURRENT_BINARY_DIR}/doc/bindings" DEPENDS pythonmodule COMMENT "Building C/Python HTML documentation with Sphinx.")
+ else()
+ set(WITH_BINDING_DOCS FALSE CACHE BOOL "Build C/Python HTML Documentation with Sphinx" FORCE)
+ message(WARNING "Sphinx not found, binding documentation will not be built.")
+ endif()
+endif()
+
+if(WITH_DOCS OR WITH_BINDING_DOCS)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/ DESTINATION ${DOCUMENTATION_INSTALL_PATH})
+endif()
diff --git a/extern/audaspace/INSTALL b/extern/audaspace/INSTALL
new file mode 100644
index 00000000000..c63206fb949
--- /dev/null
+++ b/extern/audaspace/INSTALL
@@ -0,0 +1,107 @@
+Audaspace Installation Guide
+============================
+
+This document guides through the building and installation of audaspace.
+
+The build system used to build audaspace is CMake and it allows very building the library for very different application scenarios from a very general shared library build with plugins that is suitable for system wide installations to building everything into a single static library to be linked into a standalone program.
+
+Build Dependencies
+------------------
+
+Audaspace is written in C++ 11 so a fairly recent compiler (g++ 4.8.2, clang 3.3, MSVC 2013) is needed to build it. The build system used is CMake and you need at least version 3.0. The following build dependencies are all optional, but without any it's neither possible to open sound files nor play back through the speakers. For windows a library folder called build-dependencies can be downloaded from https://github.com/audaspace/audaspace/releases.
+
+- OpenAL (input/output device)
+- SDL (output device)
+- Jack (output device)
+- libsndfile (file access)
+- ffmpeg (file access)
+- Python (language binding)
+
+Getting the Code
+----------------
+
+The audaspace source code or binary releases can be downloaded from https://github.com/audaspace/audaspace/releases.
+
+For the most recent version you can use git to get the source code.
+
+ git clone https://github.com/audaspace/audaspace.git
+
+Plugins
+-------
+
+Before diving into the exact build steps for each platform, we will have a look at plugins. There are so far two types of plugins: input and output plugins. Input plugins are for reading audio files in many different formats and output plugins are for output devices on different platforms. During the configuration audaspace's standard plugins can be enabled with their repsective `WITH_*` and `PLUGIN_*` configuration option. Plugins are built as shared libraries. By default audaspace looks in the `DEFAULT_PLUGIN_PATH` for shared libraries it can load. Building with a dependency (`WITH_*`) but without enabling the respective `PLUGIN_*` option will compile the plugin directly into the library, so the plugin always gets loaded when the plugins are initialised.
+
+Building for Linux
+------------------
+
+### Configuration ###
+
+It is highly recommended to build audaspace outside of the actual source code in a specific build directory.
+
+ mkdir build
+ cd build
+
+Configuration is then either done interactively by using ccmake
+
+ ccmake ../audaspace
+
+__or__ it can be done by defining variables directly during the run of cmake.
+
+ cmake ../build \
+ -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:STRING=Release \
+ -DBUILD_DEMOS:BOOL=TRUE \
+ -DSHARED_LIBRARY:BOOL=TRUE \
+ -DWITH_C:BOOL=TRUE \
+ -DWITH_FFMPEG:BOOL=TRUE \
+ -DWITH_JACK:BOOL=TRUE \
+ -DWITH_LIBSNDFILE:BOOL=TRUE \
+ -DWITH_OPENAL:BOOL=TRUE \
+ -DWITH_PYTHON:BOOL=TRUE \
+ -DWITH_SDL:BOOL=TRUE \
+ -DDEFAULT_PLUGIN_PATH:PATH=/usr/share/audaspace/plugins
+
+This specific configuration is recommended for a system wide installation of audaspace where all build dependencies are required.
+
+### Building ###
+
+After configuration the building is as easy as running
+
+ make
+
+### Installation ###
+
+Installation is then also simple using
+
+ make install
+
+### Using the library ###
+
+When audaspace is installed to the system, the required configuration for _pkgconfig_ is also installed and pkgconfig can then be used to compile projects with audaspace.
+
+It is also possible to build audaspace as a static library and use it directly in a project. For this the library has to be configured accordingly with ccmake and after building the resulting library file can be added to the project's build system.
+
+Building for Windows
+--------------------
+
+### Configuration ###
+
+Using cmake-gui select Visual Studio 2013 or 2015 for the architecture you want to build for and choose audaspace's source directory and a build directory. It is highly recommended to build audaspace outside of the source directory. During the first configuration cmake tries to find the dependencies. Dependencies that are not installed on the system are automatically disabled. To prevent this, enable `WITH_STRICT_DEPENDENCIES`. To use the build dependencies folder from the website, set the `LIBRARY_PATH` to point to the extracted directory. Also don't forget to set the `CMAKE_INSTALL_PREFIX` to a path where your user account can install to. Finally enable the dependencies that you want to use (`WITH_*`), configure and generate.
+
+### Building ###
+
+Open the project in Visual Studio and set the configuration to Release. Then you can simply hit the build button.
+
+### Installation ###
+
+To install audaspace to your target folder, build the INSTALL target.
+Note that if you don't use the libraries folder provided on the website, the INSTALL target might fail and you need to copy the files manually, including the dlls of the dependencies.
+
+### Using the library ###
+
+To use audaspace in your project, configure the include path and the libraries that you need, which you can find in the include and lib directories in your installation path.
+
+### Notes for plugins on windows ###
+
+- FFMPEG: Due to a problem with FFMPEG's 32 bit libraries, it is necessary to disable SAFESEH for the audffmpeg build target inside Visual Studio (Properties, Linker, Advanced). This has to be done after each generate step of CMake.
+- Jack: If no jack server is running on windows and your application or one of the demos tries to use the jack plugin, this adds a long delay to the device initialisation. In case you don't need jack, make sure to disable the plugin or for the prebuilt version of audaspace simply delete audjack.dll (and any files with jack in the name to clean up).
diff --git a/extern/audaspace/LICENSE b/extern/audaspace/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/extern/audaspace/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/extern/audaspace/README.md b/extern/audaspace/README.md
new file mode 100644
index 00000000000..7fdd515ab67
--- /dev/null
+++ b/extern/audaspace/README.md
@@ -0,0 +1,47 @@
+audaspace
+=========
+
+Audaspace (pronounced "outer space") is a high level audio library written in C++ with language bindings for Python for example. It started out as the audio engine of the 3D modelling application Blender and is now released as a standalone library.
+
+Documentation and Community
+---------------------------
+
+The documentation including guides for building and installing, demos, tutorials as well as the API reference for C++, C and python can be found on https://audaspace.github.io.
+
+Bug reports and feature requests should go to the [issue tracker](https://github.com/audaspace/audaspace/issues).
+
+For any other discussions about audaspace there is a [mailing list](https://groups.google.com/forum/#!forum/audaspace) and there is also the IRC channel #audaspace on irc.freenode.net.
+
+Features
+--------
+
+The following (probably incomplete) features are supported by audaspace:
+
+* input/output devices
+ * input from microphones, line in, etc.
+ * output devices including 3D audio support
+* file reading/writing
+* filters like low-/highpass and effects like delay, reverse or fading
+* generators for simple waveforms like silence, sine and triangle
+* respecification - this term is used for changing stream parameters which are
+ * channel count - channel remapping
+ * sample format - the library internally uses 32 bit floats
+ * sample rate - resampling
+* simple (superposition, joining and ping-pong aka forward-reverse) and more complex (non-linear audio editing) sequencing of sounds
+
+License
+-------
+
+> Copyright © 2009-2015 Jörg Müller. All rights reserved.
+>
+> Licensed under the Apache License, Version 2.0 (the "License");
+> you may not use this file except in compliance with the License.
+> You may obtain a copy of the License at
+>
+> http://www.apache.org/licenses/LICENSE-2.0
+>
+> Unless required by applicable law or agreed to in writing, software
+> distributed under the License is distributed on an "AS IS" BASIS,
+> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+> See the License for the specific language governing permissions and
+> limitations under the License.
diff --git a/extern/audaspace/bindings/C/AUD_Device.cpp b/extern/audaspace/bindings/C/AUD_Device.cpp
new file mode 100644
index 00000000000..441f228deac
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Device.cpp
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/DeviceManager.h"
+#include "devices/I3DDevice.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/ReadDevice.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Device.h"
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
+{
+ aud::DeviceSpecs s;
+ s.specs = convCToSpec(specs.specs);
+ s.format = static_cast<SampleFormat>(specs.format);
+ return s;
+}
+
+AUD_API AUD_Device* AUD_Device_open(const char* type, AUD_DeviceSpecs specs, int buffersize, const char* name)
+{
+ DeviceSpecs dspecs = convCToDSpec(specs);
+
+ if(dspecs.channels == CHANNELS_INVALID)
+ dspecs.channels = CHANNELS_STEREO;
+ if(dspecs.format == FORMAT_INVALID)
+ dspecs.format = FORMAT_FLOAT32;
+ if(dspecs.rate == RATE_INVALID)
+ dspecs.rate = RATE_48000;
+ if(buffersize < 128)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ if(name == nullptr)
+ name = "";
+
+ try
+ {
+ if(!type)
+ {
+ auto device = DeviceManager::getDevice();
+ if(!device)
+ {
+ DeviceManager::openDefaultDevice();
+ device = DeviceManager::getDevice();
+ }
+ return new AUD_Device(device);
+ }
+
+ if(type == std::string("read"))
+ {
+ return new AUD_Device(new ReadDevice(dspecs));
+ }
+
+ std::shared_ptr<IDeviceFactory> factory;
+ if(!*type)
+ factory = DeviceManager::getDefaultDeviceFactory();
+ else
+ factory = DeviceManager::getDeviceFactory(type);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setSpecs(dspecs);
+ factory->setBufferSize(buffersize);
+ return new AUD_Device(factory->openDevice());
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_Device_lock(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->lock();
+}
+
+AUD_API AUD_Handle* AUD_Device_play(AUD_Device* device, AUD_Sound* sound, int keep)
+{
+ assert(sound);
+ auto dev = device ? *device : DeviceManager::getDevice();
+
+ try
+ {
+ AUD_Handle handle = dev->play(*sound, keep);
+ if(handle.get())
+ {
+ return new AUD_Handle(handle);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_Device_stopAll(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->stopAll();
+}
+
+AUD_API void AUD_Device_unlock(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->unlock();
+}
+
+AUD_API AUD_Channels AUD_Device_getChannels(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return static_cast<AUD_Channels>(dev->getSpecs().channels);
+}
+
+AUD_API AUD_DistanceModel AUD_Device_getDistanceModel(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return static_cast<AUD_DistanceModel>(dev->getDistanceModel());
+}
+
+AUD_API void AUD_Device_setDistanceModel(AUD_Device* device, AUD_DistanceModel value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setDistanceModel(static_cast<DistanceModel>(value));
+}
+
+AUD_API float AUD_Device_getDopplerFactor(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return dev->getDopplerFactor();
+}
+
+AUD_API void AUD_Device_setDopplerFactor(AUD_Device* device, float value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setDopplerFactor(value);
+}
+
+AUD_API AUD_SampleFormat AUD_Device_getFormat(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return static_cast<AUD_SampleFormat>(dev->getSpecs().format);
+}
+
+AUD_API void AUD_Device_getListenerLocation(AUD_Device* device, float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v = dev->getListenerLocation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+}
+
+AUD_API void AUD_Device_setListenerLocation(AUD_Device* device, const float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v(value[0], value[1], value[2]);
+ dev->setListenerLocation(v);
+}
+
+AUD_API void AUD_Device_getListenerOrientation(AUD_Device* device, float value[4])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Quaternion v = dev->getListenerOrientation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ value[3] = v.w();
+}
+
+AUD_API void AUD_Device_setListenerOrientation(AUD_Device* device, const float value[4])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Quaternion v(value[3], value[0], value[1], value[2]);
+ dev->setListenerOrientation(v);
+}
+
+AUD_API void AUD_Device_getListenerVelocity(AUD_Device* device, float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v = dev->getListenerVelocity();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+}
+
+AUD_API void AUD_Device_setListenerVelocity(AUD_Device* device, const float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v(value[0], value[1], value[2]);
+ dev->setListenerVelocity(v);
+}
+
+AUD_API double AUD_Device_getRate(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return dev->getSpecs().rate;
+}
+
+AUD_API float AUD_Device_getSpeedOfSound(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return dev->getSpeedOfSound();
+}
+
+AUD_API void AUD_Device_setSpeedOfSound(AUD_Device* device, float value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setSpeedOfSound(value);
+}
+
+AUD_API float AUD_Device_getVolume(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return dev->getVolume();
+}
+
+AUD_API void AUD_Device_setVolume(AUD_Device* device, float value)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->setVolume(value);
+}
+
+AUD_API int AUD_Device_read(AUD_Device* device, unsigned char* buffer, int length)
+{
+ assert(device);
+ assert(buffer);
+
+ auto readDevice = std::dynamic_pointer_cast<ReadDevice>(*device);
+ if(!readDevice)
+ return false;
+
+ try
+ {
+ return readDevice->read(buffer, length);
+ }
+ catch(Exception&)
+ {
+ return false;
+ }
+}
+
+AUD_API void AUD_Device_free(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ delete device;
+ }
+ catch(Exception&)
+ {
+ }
+}
+
+AUD_API AUD_Device* AUD_Device_getCurrent()
+{
+ auto device = DeviceManager::getDevice();
+
+ if(!device)
+ return nullptr;
+
+ return new AUD_Device(device);
+}
+
+AUD_API void AUD_seekSynchronizer(AUD_Handle* handle, float time)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->seek(*reinterpret_cast<std::shared_ptr<IHandle>*>(handle), time);
+}
+
+AUD_API float AUD_getSynchronizerPosition(AUD_Handle* handle)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ return synchronizer->getPosition(*reinterpret_cast<std::shared_ptr<IHandle>*>(handle));
+ return (*reinterpret_cast<std::shared_ptr<IHandle>*>(handle))->getPosition();
+}
+
+AUD_API void AUD_playSynchronizer()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->play();
+}
+
+AUD_API void AUD_stopSynchronizer()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->stop();
+}
+
+AUD_API void AUD_setSynchronizerCallback(AUD_syncFunction function, void* data)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->setSyncCallback(function, data);
+}
+
+AUD_API int AUD_isSynchronizerPlaying()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ return synchronizer->isPlaying();
+ return false;
+}
+
diff --git a/extern/audaspace/bindings/C/AUD_Device.h b/extern/audaspace/bindings/C/AUD_Device.h
new file mode 100644
index 00000000000..0dfa21f0660
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Device.h
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Possible distance models for the 3D device.
+typedef enum
+{
+ AUD_DISTANCE_MODEL_INVALID = 0,
+ AUD_DISTANCE_MODEL_INVERSE,
+ AUD_DISTANCE_MODEL_INVERSE_CLAMPED,
+ AUD_DISTANCE_MODEL_LINEAR,
+ AUD_DISTANCE_MODEL_LINEAR_CLAMPED,
+ AUD_DISTANCE_MODEL_EXPONENT,
+ AUD_DISTANCE_MODEL_EXPONENT_CLAMPED
+} AUD_DistanceModel;
+
+typedef void (*AUD_syncFunction)(void*, int, float);
+
+/**
+ * Opens a new sound device.
+ * \param type The name of the device.
+ * Can be NULL to open the default device with default settings or return the handle to the already opened one.
+ * Can be "" to open the a default factory device with given settings.
+ * Can be "read" to open a readable device.
+ * \param specs Specification of the device parameters.
+ * \param buffersize Size of the mixing buffer.
+ * \param name Custom name of the device.
+ * \return A handle to the opened device or NULL on failure.
+ */
+extern AUD_API AUD_Device* AUD_Device_open(const char* type, AUD_DeviceSpecs specs, int buffersize, const char* name);
+
+/**
+ * Locks the playback device.
+ */
+extern AUD_API void AUD_Device_lock(AUD_Device* device);
+
+/**
+ * Plays back a sound file.
+ * \param sound The handle of the sound file.
+ * \param keep When keep is true the sound source will not be deleted but set to
+ * paused when its end has been reached.
+ * \return A handle to the played back sound.
+ */
+extern AUD_API AUD_Handle* AUD_Device_play(AUD_Device* device, AUD_Sound* sound, int keep);
+
+/**
+ * Stops all sounds playing.
+ */
+extern AUD_API void AUD_Device_stopAll(AUD_Device* device);
+
+/**
+ * Unlocks the device.
+ */
+extern AUD_API void AUD_Device_unlock(AUD_Device* device);
+
+/**
+ * Retrieves the channels of a device.
+ * param device The device to get the channels from.
+ * return The channels of the device.
+ */
+extern AUD_API AUD_Channels AUD_Device_getChannels(AUD_Device* device);
+
+/**
+ * Retrieves the distance model of a device.
+ * param device The device to get the distance model from.
+ * return The distance model of the device.
+ */
+extern AUD_API AUD_DistanceModel AUD_Device_getDistanceModel(AUD_Device* device);
+
+/**
+ * Sets the distance model of a device.
+ * param device The device to set the distance model from.
+ * param value The new distance model to set.
+ */
+extern AUD_API void AUD_Device_setDistanceModel(AUD_Device* device, AUD_DistanceModel value);
+
+/**
+ * Retrieves the doppler factor of a device.
+ * param device The device to get the doppler factor from.
+ * return The doppler factor of the device.
+ */
+extern AUD_API float AUD_Device_getDopplerFactor(AUD_Device* device);
+
+/**
+ * Sets the doppler factor of a device.
+ * param device The device to set the doppler factor from.
+ * param value The new doppler factor to set.
+ */
+extern AUD_API void AUD_Device_setDopplerFactor(AUD_Device* device, float value);
+
+/**
+ * Retrieves the format of a device.
+ * param device The device to get the format from.
+ * return The format of the device.
+ */
+extern AUD_API AUD_SampleFormat AUD_Device_getFormat(AUD_Device* device);
+
+/**
+ * Retrieves the listener location of a device.
+ * param device The device to get the listener location from.
+ * return The listener location of the device.
+ */
+extern AUD_API void AUD_Device_getListenerLocation(AUD_Device* device, float value[3]);
+
+/**
+ * Sets the listener location of a device.
+ * param device The device to set the listener location from.
+ * param value The new listener location to set.
+ */
+extern AUD_API void AUD_Device_setListenerLocation(AUD_Device* device, const float value[3]);
+
+/**
+ * Retrieves the listener orientation of a device.
+ * param device The device to get the listener orientation from.
+ * return The listener orientation of the device.
+ */
+extern AUD_API void AUD_Device_getListenerOrientation(AUD_Device* device, float value[4]);
+
+/**
+ * Sets the listener orientation of a device.
+ * param device The device to set the listener orientation from.
+ * param value The new listener orientation to set.
+ */
+extern AUD_API void AUD_Device_setListenerOrientation(AUD_Device* device, const float value[4]);
+
+/**
+ * Retrieves the listener velocity of a device.
+ * param device The device to get the listener velocity from.
+ * return The listener velocity of the device.
+ */
+extern AUD_API void AUD_Device_getListenerVelocity(AUD_Device* device, float value[3]);
+
+/**
+ * Sets the listener velocity of a device.
+ * param device The device to set the listener velocity from.
+ * param value The new listener velocity to set.
+ */
+extern AUD_API void AUD_Device_setListenerVelocity(AUD_Device* device, const float value[3]);
+
+/**
+ * Retrieves the rate of a device.
+ * param device The device to get the rate from.
+ * return The rate of the device.
+ */
+extern AUD_API double AUD_Device_getRate(AUD_Device* device);
+
+/**
+ * Retrieves the speed of sound of a device.
+ * param device The device to get the speed of sound from.
+ * return The speed of sound of the device.
+ */
+extern AUD_API float AUD_Device_getSpeedOfSound(AUD_Device* device);
+
+/**
+ * Sets the speed of sound of a device.
+ * param device The device to set the speed of sound from.
+ * param value The new speed of sound to set.
+ */
+extern AUD_API void AUD_Device_setSpeedOfSound(AUD_Device* device, float value);
+
+/**
+ * Retrieves the volume of a device.
+ * param device The device to get the volume from.
+ * return The volume of the device.
+ */
+extern AUD_API float AUD_Device_getVolume(AUD_Device* device);
+
+/**
+ * Sets the volume of a device.
+ * param device The device to set the volume from.
+ * param value The new volume to set.
+ */
+extern AUD_API void AUD_Device_setVolume(AUD_Device* device, float value);
+
+/**
+ * Reads the next samples into the supplied buffer.
+ * \param device The readable device.
+ * \param buffer The target buffer.
+ * \param length The length in samples to be filled.
+ * \return True if the reading succeeded, false if there are no sounds
+ * played back currently, in that case the buffer is filled with
+ * silence.
+ */
+extern AUD_API int AUD_Device_read(AUD_Device* device, unsigned char* buffer, int length);
+
+/**
+ * Closes a device. Handle becomes invalid afterwards.
+ * \param device The device to close.
+ */
+extern AUD_API void AUD_Device_free(AUD_Device* device);
+
+/**
+ * Retrieves the current device of the DeviceManager.
+ * \return A pointer to the current device, which needs to be freed with
+ * AUD_Device_free.
+ */
+extern AUD_API AUD_Device* AUD_Device_getCurrent();
+
+/**
+ * Seeks sequenced sound scene playback.
+ * \param handle Playback handle.
+ * \param time Time in seconds to seek to.
+ */
+extern AUD_API void AUD_seekSynchronizer(AUD_Handle* handle, float time);
+
+/**
+ * Returns the current sound scene playback time.
+ * \param handle Playback handle.
+ * \return The playback time in seconds.
+ */
+extern AUD_API float AUD_getSynchronizerPosition(AUD_Handle* handle);
+
+/**
+ * Starts the playback of jack transport if possible.
+ */
+extern AUD_API void AUD_playSynchronizer();
+
+/**
+ * Stops the playback of jack transport if possible.
+ */
+extern AUD_API void AUD_stopSynchronizer();
+
+/**
+ * Sets the sync callback for jack transport.
+ * \param function The callback function.
+ * \param data The data parameter for the callback.
+ */
+extern AUD_API void AUD_setSynchronizerCallback(AUD_syncFunction function, void* data);
+
+/**
+ * Returns whether jack transport is currently playing.
+ * \return Whether jack transport is currently playing.
+ */
+extern AUD_API int AUD_isSynchronizerPlaying();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp b/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp
new file mode 100644
index 00000000000..bb7a129dde3
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp
@@ -0,0 +1,144 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_DynamicMusic.h"
+
+AUD_API AUD_DynamicMusic* AUD_DynamicMusic_create(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ return new AUD_DynamicMusic(new DynamicMusic(*device));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_DynamicMusic_free(AUD_DynamicMusic* player)
+{
+ assert(player);
+ delete player;
+}
+
+AUD_API int AUD_DynamicMusic_addScene(AUD_DynamicMusic* player, AUD_Sound* scene)
+{
+ assert(player);
+ assert(scene);
+
+ return (*player)->addScene(*scene);
+}
+
+AUD_API int AUD_DynamicMusic_setSecene(AUD_DynamicMusic* player, int scene)
+{
+ assert(player);
+
+ return (*player)->changeScene(scene);
+}
+
+AUD_API int AUD_DynamicMusic_getScene(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getScene();
+}
+
+AUD_API int AUD_DynamicMusic_addTransition(AUD_DynamicMusic* player, int ini, int end, AUD_Sound* transition)
+{
+ assert(player);
+ assert(transition);
+
+ return (*player)->addTransition(ini, end, *transition);
+}
+
+AUD_API void AUD_DynamicMusic_setFadeTime(AUD_DynamicMusic* player, float seconds)
+{
+ assert(player);
+
+ (*player)->setFadeTime(seconds);
+}
+
+AUD_API float AUD_DynamicMusic_getFadeTime(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getFadeTime();
+}
+
+AUD_API int AUD_DynamicMusic_resume(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->resume();
+}
+
+AUD_API int AUD_DynamicMusic_pause(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->pause();
+}
+
+AUD_API int AUD_DynamicMusic_seek(AUD_DynamicMusic* player, float position)
+{
+ assert(player);
+
+ return (*player)->seek(position);
+}
+
+AUD_API float AUD_DynamicMusic_getPosition(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getPosition();
+}
+
+AUD_API float AUD_DynamicMusic_getVolume(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getVolume();
+}
+
+AUD_API int AUD_DynamicMusic_setVolume(AUD_DynamicMusic* player, float volume)
+{
+ assert(player);
+
+ return (*player)->setVolume(volume);
+}
+
+AUD_API AUD_Status AUD_DynamicMusic_getStatus(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return static_cast<AUD_Status>((*player)->getStatus());
+}
+
+AUD_API int AUD_DynamicMusic_stop(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->stop();
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_DynamicMusic.h b/extern/audaspace/bindings/C/AUD_DynamicMusic.h
new file mode 100644
index 00000000000..c362479591e
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_DynamicMusic.h
@@ -0,0 +1,145 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+#include "AUD_Handle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new dynamic music player.
+* \param device The device that will be used to play sounds.
+* \return The new DynamicMusic object.
+*/
+extern AUD_API AUD_DynamicMusic* AUD_DynamicMusic_create(AUD_Device* device);
+
+/**
+* Deletes a dynamic music player.
+* \param player The DynamicMusic object to be deleted.
+*/
+extern AUD_API void AUD_DynamicMusic_free(AUD_DynamicMusic* player);
+
+/**
+* Adds a sound scene to a dynamic music player.
+* \param player The DynamicMusic object.
+* \param scene The sound to be added as a scene.
+* \return The index of the new scene.
+*/
+extern AUD_API int AUD_DynamicMusic_addScene(AUD_DynamicMusic* player, AUD_Sound* scene);
+
+/**
+* Changes the current sound scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param scene The index of the scene to be played.
+* \return 0 if the target scene doesn't exist.
+*/
+extern AUD_API int AUD_DynamicMusic_setSecene(AUD_DynamicMusic* player, int scene);
+
+/**
+* Retrives the index of the current scene.
+* \param player The DynamicMusic object.
+* \return The index of the current scene.
+*/
+extern AUD_API int AUD_DynamicMusic_getScene(AUD_DynamicMusic* player);
+
+/**
+* Adds a new transition between two scenes.
+* \param player The DynamicMusic object.
+* \param ini The origin scene for the transition.
+* \param end The end scene for the transition.
+* \param transition A sound that will be used as transition between two scenes.
+* \return 0 if the ini or end scenes don't exist.
+*/
+extern AUD_API int AUD_DynamicMusic_addTransition(AUD_DynamicMusic* player, int ini, int end, AUD_Sound* transition);
+
+/**
+* Changes the fade time for the default transitions of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param seconds The amount of secods that the crossfade transition will take.
+*/
+extern AUD_API void AUD_DynamicMusic_setFadeTime(AUD_DynamicMusic* player, float seconds);
+
+/**
+* Retrieves the fade time of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The fade time of the player.
+*/
+extern AUD_API float AUD_DynamicMusic_getFadeTime(AUD_DynamicMusic* player);
+
+/**
+* Resumes the current scene playback of a dynamic music player if it is paused.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't resumed.
+*/
+extern AUD_API int AUD_DynamicMusic_resume(AUD_DynamicMusic* player);
+
+/**
+* Pauses the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't paused.
+*/
+extern AUD_API int AUD_DynamicMusic_pause(AUD_DynamicMusic* player);
+
+/**
+* Seeks the current playing scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param position The new position from which to play back, in seconds.
+* \return 0 if the seeking wasn't possible.
+*/
+extern AUD_API int AUD_DynamicMusic_seek(AUD_DynamicMusic* player, float position);
+
+/**
+* Retrieves the position of the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The position of the current playing scene.
+*/
+extern AUD_API float AUD_DynamicMusic_getPosition(AUD_DynamicMusic* player);
+
+/**
+* Retrieves the volume of the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The volume of the current playing scene.
+*/
+extern AUD_API float AUD_DynamicMusic_getVolume(AUD_DynamicMusic* player);
+
+/**
+* Changes the volume of the current scene in a dynamic music player.
+* \param player The DynamicMusic object.
+* \param 0 if the volume couldn't be changed.
+*/
+extern AUD_API int AUD_DynamicMusic_setVolume(AUD_DynamicMusic* player, float volume);
+
+/**
+* Retrieves the status of the current scene in a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The Status of the current playing scene.
+*/
+extern AUD_API AUD_Status AUD_DynamicMusic_getStatus(AUD_DynamicMusic* player);
+
+/**
+* Stops the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't stopped.
+*/
+extern AUD_API int AUD_DynamicMusic_stop(AUD_DynamicMusic* player);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_HRTF.cpp b/extern/audaspace/bindings/C/AUD_HRTF.cpp
new file mode 100644
index 00000000000..002c5d61ddd
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_HRTF.cpp
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_HRTF.h"
+
+extern AUD_API AUD_HRTF* AUD_HRTF_create()
+{
+ try
+ {
+ return new AUD_HRTF(new HRTF());
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+extern AUD_API void AUD_HRTF_free(AUD_HRTF* hrtfs)
+{
+ assert(hrtfs);
+ delete hrtfs;
+}
+
+extern AUD_API void AUD_HRTF_addImpulseResponseFromSound(AUD_HRTF* hrtfs, AUD_Sound* sound, float azimuth, float elevation)
+{
+ assert(hrtfs);
+ assert(sound);
+
+ (*hrtfs)->addImpulseResponse(std::make_shared<StreamBuffer>(*sound), azimuth, elevation);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_HRTF.h b/extern/audaspace/bindings/C/AUD_HRTF.h
new file mode 100644
index 00000000000..29dda371695
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_HRTF.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new HRTF object.
+* \return The new HRTF object.
+*/
+extern AUD_API AUD_HRTF* AUD_HRTF_create();
+
+/**
+* Deletes a HRTF object.
+* \param hrtfs The HRTF object to be deleted.
+*/
+extern AUD_API void AUD_HRTF_free(AUD_HRTF* hrtfs);
+
+/**
+* Adds a new impulse response to an HRTF object.
+* \param hrtfs The HRTF object.
+* \param sound A Sound object representing an HRTF.
+* \param azimuth The azimuth angle of the HRTF.
+* \param elevation The elevation angle of the HRTF.
+*/
+extern AUD_API void AUD_HRTF_addImpulseResponseFromSound(AUD_HRTF* hrtfs, AUD_Sound* sound, float azimuth, float elevation);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Handle.cpp b/extern/audaspace/bindings/C/AUD_Handle.cpp
new file mode 100644
index 00000000000..265c7bf08d2
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Handle.cpp
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/I3DHandle.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Handle.h"
+
+AUD_API int AUD_Handle_pause(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->pause();
+}
+
+AUD_API int AUD_Handle_resume(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->resume();
+}
+
+AUD_API int AUD_Handle_stop(AUD_Handle* handle)
+{
+ assert(handle);
+ int result = (*handle)->stop();
+ delete handle;
+ return result;
+}
+
+AUD_API float AUD_Handle_getAttenuation(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getAttenuation();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setAttenuation(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setAttenuation(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeAngleInner(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeAngleInner();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeAngleInner(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeAngleInner(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeAngleOuter(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeAngleOuter();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeAngleOuter(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeAngleOuter(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeVolumeOuter(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeVolumeOuter();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeVolumeOuter(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeVolumeOuter(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getDistanceMaximum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getDistanceMaximum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setDistanceMaximum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setDistanceMaximum(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getDistanceReference(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getDistanceReference();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setDistanceReference(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setDistanceReference(value);
+ return false;
+}
+
+AUD_API int AUD_Handle_doesKeep(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getKeep();
+}
+
+AUD_API int AUD_Handle_setKeep(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ return (*handle)->setKeep(value);
+}
+
+AUD_API int AUD_Handle_getLocation(AUD_Handle* handle, float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = h->getLocation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setLocation(AUD_Handle* handle, const float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = Vector3(value[0], value[1], value[2]);
+ return h->setLocation(v);
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_getLoopCount(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getLoopCount();
+}
+
+AUD_API int AUD_Handle_setLoopCount(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ return (*handle)->setLoopCount(value);
+}
+
+AUD_API int AUD_Handle_getOrientation(AUD_Handle* handle, float value[4])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Quaternion v = h->getOrientation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ value[3] = v.w();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setOrientation(AUD_Handle* handle, const float value[4])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Quaternion v(value[3], value[0], value[1], value[2]);
+ return h->setOrientation(v);
+ }
+ return false;
+}
+
+AUD_API float AUD_Handle_getPitch(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getPitch();
+}
+
+AUD_API int AUD_Handle_setPitch(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->setPitch(value);
+}
+
+AUD_API float AUD_Handle_getPosition(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getPosition();
+}
+
+AUD_API int AUD_Handle_setPosition(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->seek(value);
+}
+
+AUD_API int AUD_Handle_isRelative(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->isRelative();
+ return true;
+}
+
+AUD_API int AUD_Handle_setRelative(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setRelative(value);
+ return false;
+}
+
+AUD_API AUD_Status AUD_Handle_getStatus(AUD_Handle* handle)
+{
+ assert(handle);
+ return static_cast<AUD_Status>((*handle)->getStatus());
+}
+
+AUD_API int AUD_Handle_getVelocity(AUD_Handle* handle, float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = h->getVelocity();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setVelocity(AUD_Handle* handle, const float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = Vector3(value[0], value[1], value[2]);
+ return h->setVelocity(v);
+ }
+ return false;
+}
+
+AUD_API float AUD_Handle_getVolume(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getVolume();
+}
+
+AUD_API int AUD_Handle_setVolume(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->setVolume(value);
+}
+
+AUD_API float AUD_Handle_getVolumeMaximum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getVolumeMaximum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setVolumeMaximum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setVolumeMaximum(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getVolumeMinimum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getVolumeMinimum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setVolumeMinimum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setVolumeMinimum(value);
+ return false;
+}
+
+AUD_API void AUD_Handle_free(AUD_Handle* handle)
+{
+ delete handle;
+}
diff --git a/extern/audaspace/bindings/C/AUD_Handle.h b/extern/audaspace/bindings/C/AUD_Handle.h
new file mode 100644
index 00000000000..27cbd251de5
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Handle.h
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Status of a playback handle.
+typedef enum
+{
+ AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
+ AUD_STATUS_PLAYING, /// Sound is playing.
+ AUD_STATUS_PAUSED, /// Sound is being paused.
+ AUD_STATUS_STOPPED /// Sound is stopped but kept in the device.
+} AUD_Status;
+
+/**
+ * Pauses a played back sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been playing or not.
+ */
+extern AUD_API int AUD_Handle_pause(AUD_Handle* handle);
+
+/**
+ * Resumes a paused sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been paused or not.
+ */
+extern AUD_API int AUD_Handle_resume(AUD_Handle* handle);
+
+/**
+ * Stops a playing or paused sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been valid or not.
+ */
+extern AUD_API int AUD_Handle_stop(AUD_Handle* handle);
+
+/**
+ * Retrieves the attenuation of a handle.
+ * param handle The handle to get the attenuation from.
+ * return The attenuation of the handle.
+ */
+extern AUD_API float AUD_Handle_getAttenuation(AUD_Handle* handle);
+
+/**
+ * Sets the attenuation of a handle.
+ * param handle The handle to set the attenuation from.
+ * param value The new attenuation to set.
+ */
+extern AUD_API int AUD_Handle_setAttenuation(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone angle inner of a handle.
+ * param handle The handle to get the cone angle inner from.
+ * return The cone angle inner of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeAngleInner(AUD_Handle* handle);
+
+/**
+ * Sets the cone angle inner of a handle.
+ * param handle The handle to set the cone angle inner from.
+ * param value The new cone angle inner to set.
+ */
+extern AUD_API int AUD_Handle_setConeAngleInner(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone angle outer of a handle.
+ * param handle The handle to get the cone angle outer from.
+ * return The cone angle outer of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeAngleOuter(AUD_Handle* handle);
+
+/**
+ * Sets the cone angle outer of a handle.
+ * param handle The handle to set the cone angle outer from.
+ * param value The new cone angle outer to set.
+ */
+extern AUD_API int AUD_Handle_setConeAngleOuter(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone volume outer of a handle.
+ * param handle The handle to get the cone volume outer from.
+ * return The cone volume outer of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeVolumeOuter(AUD_Handle* handle);
+
+/**
+ * Sets the cone volume outer of a handle.
+ * param handle The handle to set the cone volume outer from.
+ * param value The new cone volume outer to set.
+ */
+extern AUD_API int AUD_Handle_setConeVolumeOuter(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the distance maximum of a handle.
+ * param handle The handle to get the distance maximum from.
+ * return The distance maximum of the handle.
+ */
+extern AUD_API float AUD_Handle_getDistanceMaximum(AUD_Handle* handle);
+
+/**
+ * Sets the distance maximum of a handle.
+ * param handle The handle to set the distance maximum from.
+ * param value The new distance maximum to set.
+ */
+extern AUD_API int AUD_Handle_setDistanceMaximum(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the distance reference of a handle.
+ * param handle The handle to get the distance reference from.
+ * return The distance reference of the handle.
+ */
+extern AUD_API float AUD_Handle_getDistanceReference(AUD_Handle* handle);
+
+/**
+ * Sets the distance reference of a handle.
+ * param handle The handle to set the distance reference from.
+ * param value The new distance reference to set.
+ */
+extern AUD_API int AUD_Handle_setDistanceReference(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the keep of a handle.
+ * param handle The handle to get the keep from.
+ * return The keep of the handle.
+ */
+extern AUD_API int AUD_Handle_doesKeep(AUD_Handle* handle);
+
+/**
+ * Sets the keep of a handle.
+ * param handle The handle to set the keep from.
+ * param value The new keep to set.
+ */
+extern AUD_API int AUD_Handle_setKeep(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the location of a handle.
+ * param handle The handle to get the location from.
+ * return The location of the handle.
+ */
+extern AUD_API int AUD_Handle_getLocation(AUD_Handle* handle, float value[3]);
+
+/**
+ * Sets the location of a handle.
+ * param handle The handle to set the location from.
+ * param value The new location to set.
+ */
+extern AUD_API int AUD_Handle_setLocation(AUD_Handle* handle, const float value[3]);
+
+/**
+ * Retrieves the loop count of a handle.
+ * param handle The handle to get the loop count from.
+ * return The loop count of the handle.
+ */
+extern AUD_API int AUD_Handle_getLoopCount(AUD_Handle* handle);
+
+/**
+ * Sets the loop count of a handle.
+ * param handle The handle to set the loop count from.
+ * param value The new loop count to set.
+ */
+extern AUD_API int AUD_Handle_setLoopCount(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the orientation of a handle.
+ * param handle The handle to get the orientation from.
+ * return The orientation of the handle.
+ */
+extern AUD_API int AUD_Handle_getOrientation(AUD_Handle* handle, float value[4]);
+
+/**
+ * Sets the orientation of a handle.
+ * param handle The handle to set the orientation from.
+ * param value The new orientation to set.
+ */
+extern AUD_API int AUD_Handle_setOrientation(AUD_Handle* handle, const float value[4]);
+
+/**
+ * Retrieves the pitch of a handle.
+ * param handle The handle to get the pitch from.
+ * return The pitch of the handle.
+ */
+extern AUD_API float AUD_Handle_getPitch(AUD_Handle* handle);
+
+/**
+ * Sets the pitch of a handle.
+ * param handle The handle to set the pitch from.
+ * param value The new pitch to set.
+ */
+extern AUD_API int AUD_Handle_setPitch(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the position of a handle.
+ * param handle The handle to get the position from.
+ * return The position of the handle.
+ */
+extern AUD_API float AUD_Handle_getPosition(AUD_Handle* handle);
+
+/**
+ * Sets the position of a handle.
+ * param handle The handle to set the position from.
+ * param value The new position to set.
+ */
+extern AUD_API int AUD_Handle_setPosition(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the relative of a handle.
+ * param handle The handle to get the relative from.
+ * return The relative of the handle.
+ */
+extern AUD_API int AUD_Handle_isRelative(AUD_Handle* handle);
+
+/**
+ * Sets the relative of a handle.
+ * param handle The handle to set the relative from.
+ * param value The new relative to set.
+ */
+extern AUD_API int AUD_Handle_setRelative(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the status of a handle.
+ * param handle The handle to get the status from.
+ * return The status of the handle.
+ */
+extern AUD_API AUD_Status AUD_Handle_getStatus(AUD_Handle* handle);
+
+/**
+ * Retrieves the velocity of a handle.
+ * param handle The handle to get the velocity from.
+ * return The velocity of the handle.
+ */
+extern AUD_API int AUD_Handle_getVelocity(AUD_Handle* handle, float value[3]);
+
+/**
+ * Sets the velocity of a handle.
+ * param handle The handle to set the velocity from.
+ * param value The new velocity to set.
+ */
+extern AUD_API int AUD_Handle_setVelocity(AUD_Handle* handle, const float value[3]);
+
+/**
+ * Retrieves the volume of a handle.
+ * param handle The handle to get the volume from.
+ * return The volume of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolume(AUD_Handle* handle);
+
+/**
+ * Sets the volume of a handle.
+ * param handle The handle to set the volume from.
+ * param value The new volume to set.
+ */
+extern AUD_API int AUD_Handle_setVolume(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the volume maximum of a handle.
+ * param handle The handle to get the volume maximum from.
+ * return The volume maximum of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolumeMaximum(AUD_Handle* handle);
+
+/**
+ * Sets the volume maximum of a handle.
+ * param handle The handle to set the volume maximum from.
+ * param value The new volume maximum to set.
+ */
+extern AUD_API int AUD_Handle_setVolumeMaximum(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the volume minimum of a handle.
+ * param handle The handle to get the volume minimum from.
+ * return The volume minimum of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolumeMinimum(AUD_Handle* handle);
+
+/**
+ * Sets the volume minimum of a handle.
+ * param handle The handle to set the volume minimum from.
+ * param value The new volume minimum to set.
+ */
+extern AUD_API int AUD_Handle_setVolumeMinimum(AUD_Handle* handle, float value);
+
+/**
+ * Frees a handle.
+ * \param channel Handle to free.
+ */
+extern AUD_API void AUD_Handle_free(AUD_Handle* channel);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp b/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp
new file mode 100644
index 00000000000..f3c28d4d660
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_ImpulseResponse.h"
+
+AUD_API AUD_ImpulseResponse* AUD_ImpulseResponse_create(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_ImpulseResponse(new ImpulseResponse(std::make_shared<StreamBuffer>(*sound)));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_ImpulseResponse_free(AUD_ImpulseResponse* filter)
+{
+ assert(filter);
+ delete filter;
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_ImpulseResponse.h b/extern/audaspace/bindings/C/AUD_ImpulseResponse.h
new file mode 100644
index 00000000000..dad2e87e899
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ImpulseResponse.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new ImpulseResponse object.
+* \param sound A Sound object representing a impulse response.
+* \return The new ImpulseResponse object.
+*/
+extern AUD_API AUD_ImpulseResponse* AUD_ImpulseResponse_create(AUD_Sound* sound);
+
+/**
+* Deletes a ImpulseResponse object.
+* \param threadPool The ImpulseResponse object to be deleted.
+*/
+extern AUD_API void AUD_ImpulseResponse_free(AUD_ImpulseResponse* filter);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp b/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp
new file mode 100644
index 00000000000..69ecb0987e1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp
@@ -0,0 +1,94 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_PlaybackManager.h"
+
+AUD_API AUD_PlaybackManager* AUD_PlaybackManager_create(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ return new AUD_PlaybackManager(new PlaybackManager(*device));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_PlaybackManager_free(AUD_PlaybackManager* manager)
+{
+ assert(manager);
+ delete manager;
+}
+
+AUD_API void AUD_PlaybackManager_play(AUD_PlaybackManager* manager, AUD_Sound* sound, unsigned int catKey)
+{
+ assert(manager);
+ assert(sound);
+
+ (*manager)->play(*sound, catKey);
+}
+
+AUD_API int AUD_PlaybackManager_resume(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->resume(catKey);
+}
+
+AUD_API int AUD_PlaybackManager_pause(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->pause(catKey);
+}
+
+AUD_API unsigned int AUD_PlaybackManager_addCategory(AUD_PlaybackManager* manager, float volume)
+{
+ assert(manager);
+ return (*manager)->addCategory(volume);
+}
+
+AUD_API float AUD_PlaybackManager_getVolume(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->getVolume(catKey);
+}
+
+AUD_API int AUD_PlaybackManager_setVolume(AUD_PlaybackManager* manager, float volume, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->setVolume(volume, catKey);
+}
+
+AUD_API int AUD_PlaybackManager_stop(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->stop(catKey);
+}
+
+AUD_API void AUD_PlaybackManager_clean(AUD_PlaybackManager* manager)
+{
+ assert(manager);
+ (*manager)->clean();
+}
diff --git a/extern/audaspace/bindings/C/AUD_PlaybackManager.h b/extern/audaspace/bindings/C/AUD_PlaybackManager.h
new file mode 100644
index 00000000000..0fa8171599d
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_PlaybackManager.h
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new PlaybackManager object.
+* \param device The device that will be used to play sounds.
+* \return The new PlaybackManager object.
+*/
+extern AUD_API AUD_PlaybackManager* AUD_PlaybackManager_create(AUD_Device* device);
+
+/**
+* Deletes a PlaybackManager object.
+* \param manager The PlaybackManager object to be deleted.
+*/
+extern AUD_API void AUD_PlaybackManager_free(AUD_PlaybackManager* manager);
+
+/**
+* Plays a sound through the playback manager, adding it into a category.
+* \param manager The PlaybackManager object.
+* \param sound The sound to be played.
+* \param catKey The key of the category into which the sound will be added. If it doesn't exist a new one will be creatd.
+*/
+extern AUD_API void AUD_PlaybackManager_play(AUD_PlaybackManager* manager, AUD_Sound* sound, unsigned int catKey);
+
+/**
+* Resumes the playback of all the paused sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_resume(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Pauses all the sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_pause(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Adds a new category with a custom volume.
+* \param manager The PlaybackManager object.
+* \param volume The volume value.
+* \return The key of the new category.
+*/
+extern AUD_API unsigned int AUD_PlaybackManager_addCategory(AUD_PlaybackManager* manager, float volume);
+
+/**
+* Retrieves the volume of a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return The volume of the category.
+*/
+extern AUD_API float AUD_PlaybackManager_getVolume(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Changes the voulume of a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param volume The new volume of the category.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_setVolume(AUD_PlaybackManager* manager, float volume, unsigned int catKey);
+
+/**
+* Stops all the sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_stop(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Cleans all the invalid handles in a playback manager
+* \param manager The PlaybackManager object.
+*/
+extern AUD_API void AUD_PlaybackManager_clean(AUD_PlaybackManager* manager);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp
new file mode 100644
index 00000000000..d278cb148a1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/I3DDevice.h"
+#include "devices/DeviceManager.h"
+#include "sequence/Sequence.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Sequence.h"
+
+AUD_API AUD_Sound* AUD_Sequence_create(float fps, int muted)
+{
+ // specs are changed at a later point!
+ Specs specs;
+ specs.channels = CHANNELS_STEREO;
+ specs.rate = RATE_48000;
+ AUD_Sound* sequence = new AUD_Sound(std::shared_ptr<Sequence>(new Sequence(specs, fps, muted)));
+ return sequence;
+}
+
+AUD_API void AUD_Sequence_free(AUD_Sound* sequence)
+{
+ delete sequence;
+}
+
+AUD_API AUD_SequenceEntry* AUD_Sequence_add(AUD_Sound* sequence, AUD_Sound* sound, float begin, float end, float skip)
+{
+ if(!sound)
+ return new AUD_SequenceEntry(((Sequence *)sequence->get())->add(AUD_Sound(), begin, end, skip));
+ return new AUD_SequenceEntry(((Sequence *)sequence->get())->add(*sound, begin, end, skip));
+}
+
+AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* entry)
+{
+ dynamic_cast<Sequence *>(sequence->get())->remove(*entry);
+ delete entry;
+}
+
+AUD_API void AUD_Sequence_setAnimationData(AUD_Sound* sequence, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
+{
+ AnimateableProperty* prop = dynamic_cast<Sequence *>(sequence->get())->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+ if(animated)
+ {
+ if(frame >= 0)
+ {
+ prop->write(data, frame, 1);
+ }
+ }
+ else
+ {
+ prop->write(data);
+ }
+}
+
+AUD_API AUD_DistanceModel AUD_Sequence_getDistanceModel(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return static_cast<AUD_DistanceModel>(dynamic_cast<Sequence *>(sequence->get())->getDistanceModel());
+}
+
+AUD_API void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setDistanceModel(static_cast<DistanceModel>(value));
+}
+
+AUD_API float AUD_Sequence_getDopplerFactor(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getDopplerFactor();
+}
+
+AUD_API void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setDopplerFactor(value);
+}
+
+AUD_API float AUD_Sequence_getFPS(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getFPS();
+}
+
+AUD_API void AUD_Sequence_setFPS(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setFPS(value);
+}
+
+AUD_API int AUD_Sequence_isMuted(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->isMuted();
+}
+
+AUD_API void AUD_Sequence_setMuted(AUD_Sound* sequence, int value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->mute(value);
+}
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+AUD_API AUD_Specs AUD_Sequence_getSpecs(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return convSpecToC(dynamic_cast<Sequence *>(sequence->get())->getSpecs());
+}
+
+AUD_API void AUD_Sequence_setSpecs(AUD_Sound* sequence, AUD_Specs value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setSpecs(convCToSpec(value));
+}
+
+AUD_API float AUD_Sequence_getSpeedOfSound(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getSpeedOfSound();
+}
+
+AUD_API void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setSpeedOfSound(value);
+}
+
+
+
+AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, float begin, float end, float skip)
+{
+ (*entry)->move(begin, end, skip);
+}
+
+AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
+{
+ AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(data, frame, 1);
+ }
+ else
+ {
+ prop->write(data);
+ }
+}
+
+AUD_API float AUD_SequenceEntry_getAttenuation(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getAttenuation();
+}
+
+AUD_API void AUD_SequenceEntry_setAttenuation(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setAttenuation(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeAngleInner(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeAngleInner();
+}
+
+AUD_API void AUD_SequenceEntry_setConeAngleInner(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeAngleInner(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeAngleOuter(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeAngleOuter();
+}
+
+AUD_API void AUD_SequenceEntry_setConeAngleOuter(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeAngleOuter(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeVolumeOuter(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeVolumeOuter();
+}
+
+AUD_API void AUD_SequenceEntry_setConeVolumeOuter(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeVolumeOuter(value);
+}
+
+AUD_API float AUD_SequenceEntry_getDistanceMaximum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getDistanceMaximum();
+}
+
+AUD_API void AUD_SequenceEntry_setDistanceMaximum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setDistanceMaximum(value);
+}
+
+AUD_API float AUD_SequenceEntry_getDistanceReference(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getDistanceReference();
+}
+
+AUD_API void AUD_SequenceEntry_setDistanceReference(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setDistanceReference(value);
+}
+
+AUD_API int AUD_SequenceEntry_isMuted(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->isMuted();
+}
+
+AUD_API void AUD_SequenceEntry_setMuted(AUD_SequenceEntry* sequence_entry, int value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->mute(value);
+}
+
+AUD_API int AUD_SequenceEntry_isRelative(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->isRelative();
+}
+
+AUD_API void AUD_SequenceEntry_setRelative(AUD_SequenceEntry* sequence_entry, int value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setRelative(value);
+}
+
+AUD_API AUD_Sound* AUD_SequenceEntry_getSound(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return new std::shared_ptr<ISound>((*sequence_entry)->getSound());
+}
+
+AUD_API void AUD_SequenceEntry_setSound(AUD_SequenceEntry* sequence_entry, AUD_Sound* value)
+{
+ assert(sequence_entry);
+ if(value)
+ (*sequence_entry)->setSound(*value);
+ else
+ (*sequence_entry)->setSound(AUD_Sound());
+}
+
+AUD_API float AUD_SequenceEntry_getVolumeMaximum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getVolumeMaximum();
+}
+
+AUD_API void AUD_SequenceEntry_setVolumeMaximum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setVolumeMaximum(value);
+}
+
+AUD_API float AUD_SequenceEntry_getVolumeMinimum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getVolumeMinimum();
+}
+
+AUD_API void AUD_SequenceEntry_setVolumeMinimum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setVolumeMinimum(value);
+}
diff --git a/extern/audaspace/bindings/C/AUD_Sequence.h b/extern/audaspace/bindings/C/AUD_Sequence.h
new file mode 100644
index 00000000000..668960c7d50
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sequence.h
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Possible animatable properties for Sequence Factories and Entries.
+typedef enum
+{
+ AUD_AP_VOLUME,
+ AUD_AP_PANNING,
+ AUD_AP_PITCH,
+ AUD_AP_LOCATION,
+ AUD_AP_ORIENTATION
+} AUD_AnimateablePropertyType;
+
+/**
+ * Creates a new sequenced sound scene.
+ * \param fps The FPS of the scene.
+ * \param muted Whether the scene is muted.
+ * \return The new sound scene.
+ */
+extern AUD_API AUD_Sound* AUD_Sequence_create(float fps, int muted);
+
+/**
+ * Deletes a sound scene.
+ * \param sequence The sound scene.
+ */
+extern AUD_API void AUD_Sequence_free(AUD_Sound* sequence);
+
+/**
+ * Adds a new entry to the scene.
+ * \param sequence The sound scene.
+ * \param sound The sound this entry should play.
+ * \param begin The start time.
+ * \param end The end time or a negative value if determined by the sound.
+ * \param skip How much seconds should be skipped at the beginning.
+ * \return The entry added.
+ */
+extern AUD_API AUD_SequenceEntry* AUD_Sequence_add(AUD_Sound* sequence, AUD_Sound* sound, float begin, float end, float skip);
+
+/**
+ * Removes an entry from the scene.
+ * \param sequence The sound scene.
+ * \param entry The entry to remove.
+ */
+extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* entry);
+
+/**
+ * Writes animation data to a sequence.
+ * \param sequence The sound scene.
+ * \param type The type of animation data.
+ * \param frame The frame this data is for.
+ * \param data The data to write.
+ * \param animated Whether the attribute is animated.
+ */
+extern AUD_API void AUD_Sequence_setAnimationData(AUD_Sound* sequence, AUD_AnimateablePropertyType type, int frame, float* data, char animated);
+
+/**
+ * Retrieves the distance model of a sequence.
+ * param sequence The sequence to get the distance model from.
+ * return The distance model of the sequence.
+ */
+extern AUD_API AUD_DistanceModel AUD_Sequence_getDistanceModel(AUD_Sound* sequence);
+
+/**
+ * Sets the distance model of a sequence.
+ * param sequence The sequence to set the distance model from.
+ * param value The new distance model to set.
+ */
+extern AUD_API void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value);
+
+/**
+ * Retrieves the doppler factor of a sequence.
+ * param sequence The sequence to get the doppler factor from.
+ * return The doppler factor of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getDopplerFactor(AUD_Sound* sequence);
+
+/**
+ * Sets the doppler factor of a sequence.
+ * param sequence The sequence to set the doppler factor from.
+ * param value The new doppler factor to set.
+ */
+extern AUD_API void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value);
+
+/**
+ * Retrieves the fps of a sequence.
+ * param sequence The sequence to get the fps from.
+ * return The fps of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getFPS(AUD_Sound* sequence);
+
+/**
+ * Sets the fps of a sequence.
+ * param sequence The sequence to set the fps from.
+ * param value The new fps to set.
+ */
+extern AUD_API void AUD_Sequence_setFPS(AUD_Sound* sequence, float value);
+
+/**
+ * Retrieves the muted of a sequence.
+ * param sequence The sequence to get the muted from.
+ * return The muted of the sequence.
+ */
+extern AUD_API int AUD_Sequence_isMuted(AUD_Sound* sequence);
+
+/**
+ * Sets the muted of a sequence.
+ * param sequence The sequence to set the muted from.
+ * param value The new muted to set.
+ */
+extern AUD_API void AUD_Sequence_setMuted(AUD_Sound* sequence, int value);
+
+/**
+ * Retrieves the specs of a sequence.
+ * param sequence The sequence to get the specs from.
+ * return The specs of the sequence.
+ */
+extern AUD_API AUD_Specs AUD_Sequence_getSpecs(AUD_Sound* sequence);
+
+/**
+ * Sets the specs of a sequence.
+ * param sequence The sequence to set the specs from.
+ * param value The new specs to set.
+ */
+extern AUD_API void AUD_Sequence_setSpecs(AUD_Sound* sequence, AUD_Specs value);
+
+/**
+ * Retrieves the speed of sound of a sequence.
+ * param sequence The sequence to get the speed of sound from.
+ * return The speed of sound of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getSpeedOfSound(AUD_Sound* sequence);
+
+/**
+ * Sets the speed of sound of a sequence.
+ * param sequence The sequence to set the speed of sound from.
+ * param value The new speed of sound to set.
+ */
+extern AUD_API void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value);
+
+
+
+/**
+ * Moves the entry.
+ * \param entry The sequenced entry.
+ * \param begin The new start time.
+ * \param end The new end time or a negative value if unknown.
+ * \param skip How many seconds to skip at the beginning.
+ */
+extern AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, float begin, float end, float skip);
+
+/**
+ * Writes animation data to a sequenced entry.
+ * \param entry The sequenced entry.
+ * \param type The type of animation data.
+ * \param frame The frame this data is for.
+ * \param data The data to write.
+ * \param animated Whether the attribute is animated.
+ */
+extern AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated);
+
+/**
+ * Retrieves the attenuation of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the attenuation from.
+ * return The attenuation of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getAttenuation(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the attenuation of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the attenuation from.
+ * param value The new attenuation to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setAttenuation(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone angle inner of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone angle inner from.
+ * return The cone angle inner of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeAngleInner(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone angle inner of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone angle inner from.
+ * param value The new cone angle inner to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeAngleInner(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone angle outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone angle outer from.
+ * return The cone angle outer of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeAngleOuter(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone angle outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone angle outer from.
+ * param value The new cone angle outer to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeAngleOuter(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone volume outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone volume outer from.
+ * return The cone volume outer of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeVolumeOuter(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone volume outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone volume outer from.
+ * param value The new cone volume outer to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeVolumeOuter(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the distance maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the distance maximum from.
+ * return The distance maximum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getDistanceMaximum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the distance maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the distance maximum from.
+ * param value The new distance maximum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setDistanceMaximum(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the distance reference of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the distance reference from.
+ * return The distance reference of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getDistanceReference(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the distance reference of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the distance reference from.
+ * param value The new distance reference to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setDistanceReference(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the muted of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the muted from.
+ * return The muted of the sequence_entry.
+ */
+extern AUD_API int AUD_SequenceEntry_isMuted(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the muted of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the muted from.
+ * param value The new muted to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setMuted(AUD_SequenceEntry* sequence_entry, int value);
+
+/**
+ * Retrieves the relative of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the relative from.
+ * return The relative of the sequence_entry.
+ */
+extern AUD_API int AUD_SequenceEntry_isRelative(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the relative of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the relative from.
+ * param value The new relative to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setRelative(AUD_SequenceEntry* sequence_entry, int value);
+
+/**
+ * Retrieves the sound of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the sound from.
+ * return The sound of the sequence_entry.
+ */
+extern AUD_API AUD_Sound* AUD_SequenceEntry_getSound(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the sound of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the sound from.
+ * param value The new sound to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setSound(AUD_SequenceEntry* sequence_entry, AUD_Sound* value);
+
+/**
+ * Retrieves the volume maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the volume maximum from.
+ * return The volume maximum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getVolumeMaximum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the volume maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the volume maximum from.
+ * param value The new volume maximum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setVolumeMaximum(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the volume minimum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the volume minimum from.
+ * return The volume minimum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getVolumeMinimum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the volume minimum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the volume minimum from.
+ * param value The new volume minimum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setVolumeMinimum(AUD_SequenceEntry* sequence_entry, float value);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sound.cpp b/extern/audaspace/bindings/C/AUD_Sound.cpp
new file mode 100644
index 00000000000..30860acde62
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sound.cpp
@@ -0,0 +1,709 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Sawtooth.h"
+#include "generator/Sine.h"
+#include "generator/Silence.h"
+#include "generator/Square.h"
+#include "generator/Triangle.h"
+#include "file/File.h"
+#include "file/FileWriter.h"
+#include "util/StreamBuffer.h"
+#include "fx/Accumulator.h"
+#include "fx/ADSR.h"
+#include "fx/Delay.h"
+#include "fx/Envelope.h"
+#include "fx/Fader.h"
+#include "fx/Highpass.h"
+#include "fx/IIRFilter.h"
+#include "fx/Limiter.h"
+#include "fx/Loop.h"
+#include "fx/Lowpass.h"
+#include "fx/Pitch.h"
+#include "fx/Reverse.h"
+#include "fx/Sum.h"
+#include "fx/Threshold.h"
+#include "fx/Volume.h"
+#include "fx/SoundList.h"
+#include "fx/MutableSound.h"
+#include "sequence/Double.h"
+#include "sequence/Superpose.h"
+#include "sequence/PingPong.h"
+#include "respec/LinearResample.h"
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#ifdef WITH_CONVOLUTION
+#include "fx/BinauralSound.h"
+#include "fx/ConvolverSound.h"
+#endif
+
+#include <cassert>
+#include <cstring>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Sound.h"
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+AUD_API AUD_Specs AUD_Sound_getSpecs(AUD_Sound* sound)
+{
+ assert(sound);
+
+ return convSpecToC((*sound)->createReader()->getSpecs());
+}
+
+AUD_API int AUD_Sound_getLength(AUD_Sound* sound)
+{
+ assert(sound);
+
+ return (*sound)->createReader()->getLength();
+}
+
+AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs)
+{
+ assert(sound);
+ assert(length);
+ assert(specs);
+
+ auto stream_buffer = std::dynamic_pointer_cast<StreamBuffer>(*sound);
+ if(!stream_buffer)
+ stream_buffer = std::make_shared<StreamBuffer>(*sound);
+ *specs = convSpecToC(stream_buffer->getSpecs());
+ auto buffer = stream_buffer->getBuffer();
+
+ *length = buffer->getSize() / AUD_SAMPLE_SIZE((*specs));
+
+ sample_t* data = new sample_t[buffer->getSize()];
+
+ std::memcpy(data, buffer->getBuffer(), buffer->getSize());
+
+ return data;
+}
+
+AUD_API void AUD_Sound_freeData(sample_t* data)
+{
+ delete[] data;
+}
+
+AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_SampleRate rate, AUD_Channels channels, AUD_SampleFormat format, AUD_Container container, AUD_Codec codec, int bitrate, int buffersize)
+{
+ assert(sound);
+ assert(filename);
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*sound)->createReader();
+
+ DeviceSpecs specs;
+ specs.specs = reader->getSpecs();
+
+ if((rate != RATE_INVALID) && (specs.rate != rate))
+ {
+ specs.rate = rate;
+ reader = std::make_shared<JOSResampleReader>(reader, rate);
+ }
+
+ if((channels != AUD_CHANNELS_INVALID) && (specs.channels != static_cast<Channels>(channels)))
+ {
+ specs.channels = static_cast<Channels>(channels);
+ reader = std::make_shared<ChannelMapperReader>(reader, specs.channels);
+ }
+
+ if(format == AUD_FORMAT_INVALID)
+ format = AUD_FORMAT_S16;
+ specs.format = static_cast<SampleFormat>(format);
+
+ const char* invalid_container_error = "Container could not be determined from filename.";
+
+ if(container == AUD_CONTAINER_INVALID)
+ {
+ std::string path = filename;
+
+ if(path.length() < 4)
+ return invalid_container_error;
+
+ std::string extension = path.substr(path.length() - 4);
+
+ if(extension == ".ac3")
+ container = AUD_CONTAINER_AC3;
+ else if(extension == "flac")
+ container = AUD_CONTAINER_FLAC;
+ else if(extension == ".mkv")
+ container = AUD_CONTAINER_MATROSKA;
+ else if(extension == ".mp2")
+ container = AUD_CONTAINER_MP2;
+ else if(extension == ".mp3")
+ container = AUD_CONTAINER_MP3;
+ else if(extension == ".ogg")
+ container = AUD_CONTAINER_OGG;
+ else if(extension == ".wav")
+ container = AUD_CONTAINER_WAV;
+ else
+ return invalid_container_error;
+ }
+
+ if(codec == AUD_CODEC_INVALID)
+ {
+ switch(container)
+ {
+ case AUD_CONTAINER_AC3:
+ codec = AUD_CODEC_AC3;
+ break;
+ case AUD_CONTAINER_FLAC:
+ codec = AUD_CODEC_FLAC;
+ break;
+ case AUD_CONTAINER_MATROSKA:
+ codec = AUD_CODEC_OPUS;
+ break;
+ case AUD_CONTAINER_MP2:
+ codec = AUD_CODEC_MP2;
+ break;
+ case AUD_CONTAINER_MP3:
+ codec = AUD_CODEC_MP3;
+ break;
+ case AUD_CONTAINER_OGG:
+ codec = AUD_CODEC_VORBIS;
+ break;
+ case AUD_CONTAINER_WAV:
+ codec = AUD_CODEC_PCM;
+ break;
+ default:
+ return "Unknown container, cannot select default codec.";
+ }
+ }
+
+ if(buffersize <= 0)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, specs, static_cast<Container>(container), static_cast<Codec>(codec), bitrate);
+ FileWriter::writeReader(reader, writer, 0, buffersize);
+ }
+ catch(Exception& e)
+ {
+ return "An exception occured while writing.";
+ }
+
+ return nullptr;
+}
+
+AUD_API AUD_Sound* AUD_Sound_buffer(sample_t* data, int length, AUD_Specs specs)
+{
+ assert(data);
+
+ if(length <= 0 || specs.rate <= 0 || specs.channels <= 0)
+ {
+ return nullptr;
+ }
+
+ int size = length * AUD_SAMPLE_SIZE(specs);
+
+ std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(size);
+
+ std::memcpy(buffer->getBuffer(), data, size);
+
+ try
+ {
+ return new AUD_Sound(new StreamBuffer(buffer, convCToSpec(specs)));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size)
+{
+ assert(buffer);
+ return new AUD_Sound(new File(buffer, size));
+}
+
+AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new StreamBuffer(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_file(const char* filename)
+{
+ assert(filename);
+ return new AUD_Sound(new File(filename));
+}
+
+AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Sawtooth(frequency, rate));
+}
+
+AUD_API AUD_Sound*AUD_Sound_silence()
+{
+ return new AUD_Sound(new Silence());
+}
+
+AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Sine(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Square(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Triangle(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Accumulator(*sound, additive));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new ADSR(*sound, attack, decay, sustain, release));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Delay(*sound, delay));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Envelope(*sound, attack, release, threshold, arthreshold));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Fader(*sound, FADE_IN, start, length));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Fader(*sound, FADE_OUT, start, length));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length)
+{
+ assert(sound);
+
+ try
+ {
+ std::vector<float> a_coeff, b_coeff;
+
+ if(b)
+ for(int i = 0; i < b_length; i++)
+ b_coeff.push_back(b[i]);
+
+ if(a)
+ {
+ for(int i = 0; i < a_length; i++)
+ a_coeff.push_back(a[i]);
+
+ if(*a == 0.0f)
+ a_coeff[0] = 1.0f;
+ }
+
+ return new AUD_Sound(new IIRFilter(*sound, b_coeff, a_coeff));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Highpass(*sound, frequency, Q));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Limiter(*sound, start, end));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Loop(*sound, count));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Lowpass(*sound, frequency, Q));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Pitch(*sound, factor));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels)
+{
+ assert(sound);
+
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = static_cast<Channels>(channels);
+ specs.rate = RATE_INVALID;
+ specs.format = FORMAT_INVALID;
+ return new AUD_Sound(new ChannelMapper(*sound, specs));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality)
+{
+ assert(sound);
+
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.rate = rate;
+ specs.format = FORMAT_INVALID;
+ if(high_quality)
+ return new AUD_Sound(new JOSResample(*sound, specs));
+ else
+ return new AUD_Sound(new LinearResample(*sound, specs));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Reverse(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Sum(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Threshold(*sound, threshold));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Volume(*sound, volume));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second)
+{
+ assert(first);
+ assert(second);
+
+ try
+ {
+ return new AUD_Sound(new Double(*first, *second));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second)
+{
+ assert(first);
+ assert(second);
+
+ try
+ {
+ return new AUD_Sound(new Superpose(*first, *second));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new PingPong(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_Sound_free(AUD_Sound* sound)
+{
+ assert(sound);
+ delete sound;
+}
+
+AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound)
+{
+ return new std::shared_ptr<ISound>(*sound);
+}
+
+AUD_API AUD_Sound* AUD_Sound_list(int random)
+{
+ try
+ {
+ return new AUD_Sound(new SoundList(random));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API int AUD_SoundList_addSound(AUD_Sound* list, AUD_Sound* sound)
+{
+ assert(sound);
+ assert(list);
+
+ std::shared_ptr<SoundList> s = std::dynamic_pointer_cast<SoundList>(*list);
+ if(s.get())
+ {
+ s->addSound(*sound);
+ return 1;
+ }
+ else
+ return 0;
+
+}
+
+AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new MutableSound(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+#ifdef WITH_CONVOLUTION
+
+AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool)
+{
+ assert(sound);
+ assert(filter);
+ assert(threadPool);
+
+ try
+ {
+ return new AUD_Sound(new ConvolverSound(*sound, *filter, *threadPool));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool)
+{
+ assert(sound);
+ assert(hrtfs);
+ assert(source);
+ assert(threadPool);
+
+ try
+ {
+ return new AUD_Sound(new BinauralSound(*sound, *hrtfs, *source, *threadPool));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sound.h b/extern/audaspace/bindings/C/AUD_Sound.h
new file mode 100644
index 00000000000..b18e3c3a8eb
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sound.h
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Retrieves the sample specification of the sound.
+ * \param sound The sound to retrieve from.
+ * \return The sample specification of the sound.
+ * \note This function creates a reader from the sound and deletes it again.
+ */
+extern AUD_API AUD_Specs AUD_Sound_getSpecs(AUD_Sound* sound);
+
+/**
+ * Retrieves the approximate length of the sound.
+ * \param sound The sound to retrieve from.
+ * \return The length of the sound in samples.
+ * \note This function creates a reader from the sound and deletes it again.
+ */
+extern AUD_API int AUD_getLength(AUD_Sound* sound);
+
+/**
+ * Reads a sound's samples into memory.
+ * \param sound The sound to read.
+ * \param length Pointer to store the length of memory read.
+ * \param specs Pointer to store the data's sample specification.
+ * \return A pointer to the sample data.
+ * \warning The data has to be freed with AUD_Sound_freeData.
+ */
+extern AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs);
+
+/**
+ * Frees a buffer previously allocated with AUD_Sound_data.
+ * \param data The buffer to be freed.
+ */
+extern AUD_API void AUD_Sound_freeData(sample_t* data);
+
+/**
+ * Writes the sound to a file.
+ * \param sound The sound to write.
+ * \param filename The path to write to..
+ * \param rate The sample rate to write with.
+ * \param channels The number of channels to write with.
+ * \param format The sample format to write with.
+ * \param container The container format for the file.
+ * \param codec The codec to use in the file.
+ * \param bitrate The bitrate to write with.
+ * \param buffersize The size of the writing buffer.
+ * \return A nullptr or an error message in case of error.
+ * \note Most parameters can be set to zero for default values.
+ */
+extern AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_SampleRate rate, AUD_Channels channels, AUD_SampleFormat format, AUD_Container container, AUD_Codec codec, int bitrate, int buffersize);
+
+/**
+ * Creates a sound from a data buffer.
+ * \param data The data as interleaved samples.
+ * \param length The data's length in samples.
+ * \param specs The data's sample specification.
+ * \return A handle of the sound.
+ * \note The data gets copied to an internal memory buffer.
+ * The pointer does not need to stay valid for the lifetime of the object.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_buffer(sample_t* data, int length, AUD_Specs specs);
+
+/**
+ * Loads a sound file from a memory buffer.
+ * \param buffer The buffer which contains the sound file.
+ * \param size The size of the buffer.
+ * \return A handle of the sound file.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size);
+
+/**
+ * Caches a sound into a memory buffer.
+ * \param sound The sound to cache.
+ * \return A handle of the cached sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound);
+
+/**
+ * Loads a sound file.
+ * \param filename The filename of the sound file.
+ * \return A handle of the sound file.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_file(const char* filename);
+
+/**
+ * Creates a sawtooth sound.
+ * \param frequency The frequency of the generated sawtooth sound.
+ * \param rate The sample rate of the sawtooth sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a quiet sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_silence();
+
+/**
+ * Creates a sine sound.
+ * \param frequency The frequency of the generated sine sound.
+ * \param rate The sample rate of the sine sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a square sound.
+ * \param frequency The frequency of the generated square sound.
+ * \param rate The sample rate of the square sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a triangle sound.
+ * \param frequency The frequency of the generated triangle sound.
+ * \param rate The sample rate of the triangle sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate);
+
+/**
+ * Accumulates a sound by summing over positive input differences thus generating a monotonic sigal.
+ * If additivity is set to true negative input differences get added too, but positive ones with a factor of two.
+ * Note that with additivity the signal is not monotonic anymore.
+ * \param sound The sound to accumulate.
+ * \param additive Whether the accumulation should be additive or not.
+ * \return A handle of the accumulated sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive);
+
+/**
+ * Attack-Decay-Sustain-Release envelopes the volume of a sound.
+ * Note: there is currently no way to trigger the release with this API.
+ * \param sound The sound to filter.
+ * \param attack The attack time in seconds.
+ * \param decay The decay time in seconds.
+ * \param sustain The sustain level.
+ * \param release The release time in seconds.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release);
+
+/**
+ * Delays a sound.
+ * \param sound The sound to dealy.
+ * \param delay The delay in seconds.
+ * \return A handle of the delayed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay);
+
+/**
+ * Envelopes a sound.
+ * \param sound The sound to envelope.
+ * \param attack The attack factor.
+ * \param release The release factor.
+ * \param threshold The general threshold value.
+ * \param arthreshold The attack/release threshold value.
+ * \return A handle of the enveloped sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold);
+
+/**
+ * Fade in a sound.
+ * \param sound The sound to be fade in.
+ * \param start The time when the fading should start in seconds.
+ * \param length The duration of the fade in seconds.
+ * \return A handle of the faded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length);
+
+/**
+ * Fade out a sound.
+ * \param sound The sound to be fade out.
+ * \param start The time when the fading should start in seconds.
+ * \param length The duration of the fade in seconds.
+ * \return A handle of the faded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length);
+
+/**
+ * Filter a sound.
+ * \param sound The sound to be filtered.
+ * \param b The nominator filter coefficients, may be NULL.
+ * \param b_length The length of the b array.
+ * \param a The denominator filter coefficients, may be NULL.
+ * \param a_length The length of the a array.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length);
+
+/**
+ * Highpass filters a sound.
+ * \param sound The sound to filter.
+ * \param frequency The filter cut-off frequency.
+ * \param Q The filter quality. If usunsure which value to use, pass 1.0f.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q);
+
+/**
+ * Limits a sound.
+ * \param sound The sound to limit.
+ * \param start The start time in seconds.
+ * \param end The stop time in seconds.
+ * \return A handle of the limited sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end);
+
+/**
+ * Loops a sound.
+ * \param sound The sound to loop.
+ * \param count How often the sound should be looped. Negative values mean endlessly.
+ * \return A handle of the looped sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count);
+
+/**
+ * Lowpass filters a sound.
+ * \param sound The sound to filter.
+ * \param frequency The filter cut-off frequency.
+ * \param Q The filter quality. If usunsure which value to use, pass 1.0f.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q);
+
+/**
+ * Changes the pitch of a sound.
+ * \param sound The sound to change.
+ * \param factor The factor to change the pitch with.
+ * \return A handle of the pitched sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor);
+
+/**
+ * Rechannels the sound.
+ * \param sound The sound to rechannel.
+ * \param channels The new channel configuration.
+ * \return The rechanneled sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels);
+
+/**
+ * Resamples the sound.
+ * \param sound The sound to resample.
+ * \param rate The new sample rate.
+ * \param high_quality When true use a higher quality but slower resampler.
+ * \return The resampled sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality);
+
+/**
+ * Reverses a sound. Make sure the sound source can be reversed.
+ * \param sound The sound to reverse.
+ * \return A handle of the reversed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound);
+
+/**
+ * Sums the samples of a sound.
+ * \param sound The sound to sum.
+ * \return A handle of the summed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound);
+
+/**
+ * Turns a sound into a square wave by thresholding.
+ * \param sound The sound to threshold.
+ * \param threshold Threshold value over which an amplitude counts non-zero.
+ * \return A handle of the thresholded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold);
+
+/**
+ * Changes the volume of a sound.
+ * \param sound The sound to change.
+ * \param volume The new volume of the sound. Should be in the range 0 to 1. Use higher values with caution.
+ * \return A handle of the amplified sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume);
+
+/**
+ * Joins two sound, which means playing them one after the other.
+ * \param first The first sound.
+ * \param second The second sound.
+ * \return A handle of the joined sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second);
+
+/**
+ * Mixes two sound, which means superposing the sound samples.
+ * \param first The first sound.
+ * \param second The second sound.
+ * \return A handle of the mixed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second);
+
+/**
+ * Ping pongs a sound.
+ * \param sound The sound to ping pong.
+ * \return A handle of the ping pong sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound);
+
+/**
+ * Unloads a sound of any type.
+ * \param sound The handle of the sound.
+ */
+extern AUD_API void AUD_Sound_free(AUD_Sound* sound);
+
+/**
+ * Copies a sound.
+ * \param sound Sound to copy.
+ * \return Copied sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound);
+
+/**
+ * Creates an empty sound list that can contain several sounds.
+ * \param random A flag that indicates how the list will be played: Randomly or sequentially.
+ * if 0 the playback will be sequential, if not 0 the playback will be random.
+ * \return A handle of the sound list.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_list(int random);
+
+/**
+* Adds a new sound to a sound list.
+ * \param list The sound list in which the sound will be added.
+ * \param sound The sound that will be added to the list.
+ * \return 0 if the sound couldn't be added (the list parameter isn't a sound list).
+*/
+extern AUD_API int AUD_SoundList_addSound(AUD_Sound* list, AUD_Sound* sound);
+
+/**
+ * Creates a sound that will be restarted when sought backwards. If the original sound is a sound list, the playing sound can change.
+ * \param sound The handle of the sound.
+ * \return A handle of the mutable sound.
+*/
+extern AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound);
+
+#ifdef WITH_CONVOLUTION
+ extern AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool);
+ extern AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Source.cpp b/extern/audaspace/bindings/C/AUD_Source.cpp
new file mode 100644
index 00000000000..c4bf6fea6a1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Source.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Source.h"
+
+extern AUD_API AUD_Source* AUD_Source_create(float azimuth, float elevation, float distance)
+{
+ try
+ {
+ return new AUD_Source(new Source(azimuth, elevation, distance));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+extern AUD_API void AUD_Source_free(AUD_Source* source)
+{
+ assert(source);
+ delete source;
+}
+
+extern AUD_API float AUD_Source_getAzimuth(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getAzimuth();
+}
+
+extern AUD_API float AUD_Source_getElevation(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getElevation();
+}
+
+extern AUD_API float AUD_Source_getDistance(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getDistance();
+}
+
+extern AUD_API void AUD_Source_setAzimuth(AUD_Source* source, float azimuth)
+{
+ assert(source);
+
+ (*source)->setAzimuth(azimuth);
+}
+
+extern AUD_API void AUD_Source_setElevation(AUD_Source* source, float elevation)
+{
+ assert(source);
+
+ (*source)->setElevation(elevation);
+}
+
+extern AUD_API void AUD_Source_setDistance(AUD_Source* source, float distance)
+{
+ assert(source);
+
+ (*source)->setDistance(distance);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Source.h b/extern/audaspace/bindings/C/AUD_Source.h
new file mode 100644
index 00000000000..6ff045ec848
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Source.h
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new Source object.
+* \param azimuth The azimuth angle.
+* \param elevation The elevation angle.
+* \param elevation The distance value. [0,1]
+* \return The new Source object.
+*/
+extern AUD_API AUD_Source* AUD_Source_create(float azimuth, float elevation, float distance);
+
+/**
+* Deletes a Source object.
+* \param source The Source object to be deleted.
+*/
+extern AUD_API void AUD_Source_free(AUD_Source* source);
+
+/**
+* Retrieves the azimuth angle of a Source object.
+* \param source The Source object.
+* \return The azimuth angle.
+*/
+extern AUD_API float AUD_Source_getAzimuth(AUD_Source* source);
+
+/**
+* Retrieves the elevation angle oa a Source object.
+* \param source The Source object.
+* \return The elevation angle.
+*/
+extern AUD_API float AUD_Source_getElevation(AUD_Source* source);
+
+/**
+* Retrieves the distance of a Source object. [0,1]
+* \param source The Source object.
+* \return The distance.
+*/
+extern AUD_API float AUD_Source_getDistance(AUD_Source* distance);
+
+/**
+* Changes the azimuth angle of a Source object.
+* \param source The Source object.
+* \param azimuth The azimuth angle.
+*/
+extern AUD_API void AUD_Source_setAzimuth(AUD_Source* source, float azimuth);
+
+/**
+* Changes the elevation angle of a Source object.
+* \param source The Source object.
+* \param elevation The elevation angle.
+*/
+extern AUD_API void AUD_Source_setElevation(AUD_Source* source, float elevation);
+
+/**
+* Changes the distance of a Source object. [0,1]
+* \param source The Source object.
+* \param distance The distance.
+*/
+extern AUD_API void AUD_Source_setDistance(AUD_Source* source, float distance);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Special.cpp b/extern/audaspace/bindings/C/AUD_Special.cpp
new file mode 100644
index 00000000000..f8f46651231
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Special.cpp
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "Exception.h"
+#include "IReader.h"
+#include "file/File.h"
+#include "respec/ChannelMapper.h"
+#include "fx/Lowpass.h"
+#include "fx/Highpass.h"
+#include "fx/Envelope.h"
+#include "respec/LinearResample.h"
+#include "fx/Threshold.h"
+#include "fx/Accumulator.h"
+#include "fx/Sum.h"
+#include "generator/Silence.h"
+#include "fx/Limiter.h"
+#include "devices/DeviceManager.h"
+#include "sequence/Sequence.h"
+#include "file/FileWriter.h"
+#include "devices/ReadDevice.h"
+#include "plugin/PluginManager.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/NULLDevice.h"
+
+#include <cassert>
+#include <cstring>
+#include <cmath>
+#include <sstream>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Special.h"
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+static inline AUD_DeviceSpecs convDSpecToC(aud::DeviceSpecs specs)
+{
+ AUD_DeviceSpecs s;
+ s.specs = convSpecToC(specs.specs);
+ s.format = static_cast<AUD_SampleFormat>(specs.format);
+ return s;
+}
+
+static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
+{
+ aud::DeviceSpecs s;
+ s.specs = convCToSpec(specs.specs);
+ s.format = static_cast<SampleFormat>(specs.format);
+ return s;
+}
+
+AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
+{
+ assert(sound);
+
+ AUD_SoundInfo info;
+ info.specs.channels = AUD_CHANNELS_INVALID;
+ info.specs.rate = AUD_RATE_INVALID;
+ info.length = 0.0f;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*sound)->createReader();
+
+ if(reader.get())
+ {
+ info.specs = convSpecToC(reader->getSpecs());
+ info.length = reader->getLength() / (float) info.specs.rate;
+ }
+ }
+ catch(Exception&)
+ {
+ }
+
+ return info;
+}
+
+AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, double samplerate, int* length)
+{
+ Buffer buffer;
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_MONO;
+ specs.rate = (SampleRate)samplerate;
+ std::shared_ptr<ISound> sound;
+
+ std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename));
+
+ int position = 0;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = file->createReader();
+
+ SampleRate rate = reader->getSpecs().rate;
+
+ sound = std::shared_ptr<ISound>(new ChannelMapper(file, specs));
+
+ if(high < rate)
+ sound = std::shared_ptr<ISound>(new Lowpass(sound, high));
+ if(low > 0)
+ sound = std::shared_ptr<ISound>(new Highpass(sound, low));
+
+ sound = std::shared_ptr<ISound>(new Envelope(sound, attack, release, threshold, 0.1f));
+ sound = std::shared_ptr<ISound>(new LinearResample(sound, specs));
+
+ if(square)
+ sound = std::shared_ptr<ISound>(new Threshold(sound, sthreshold));
+
+ if(accumulate)
+ sound = std::shared_ptr<ISound>(new Accumulator(sound, additive));
+ else if(additive)
+ sound = std::shared_ptr<ISound>(new Sum(sound));
+
+ reader = sound->createReader();
+
+ if(!reader.get())
+ return nullptr;
+
+ int len;
+ bool eos;
+ do
+ {
+ len = samplerate;
+ buffer.resize((position + len) * sizeof(float), true);
+ reader->read(len, eos, buffer.getBuffer() + position);
+ position += len;
+ } while(!eos);
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+
+ float * result = (float *)malloc(position * sizeof(float));
+ std::memcpy(result, buffer.getBuffer(), position * sizeof(float));
+ *length = position;
+ return result;
+}
+
+static void pauseSound(AUD_Handle* handle)
+{
+ assert(handle);
+ (*handle)->pause();
+}
+
+AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
+{
+ std::shared_ptr<ISound> silence = std::shared_ptr<ISound>(new Silence);
+ std::shared_ptr<ISound> limiter = std::shared_ptr<ISound>(new Limiter(silence, 0, seconds));
+
+ auto device = DeviceManager::getDevice();
+
+ std::lock_guard<ILockable> lock(*device);
+
+ try
+ {
+ AUD_Handle handle2 = device->play(limiter);
+ if(handle2.get())
+ {
+ handle2->setStopCallback((stopCallback)pauseSound, handle);
+ return new AUD_Handle(handle2);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+
+ return nullptr;
+}
+
+AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt)
+{
+ DeviceSpecs specs;
+ float* buf;
+ Buffer aBuffer;
+
+ specs.rate = RATE_INVALID;
+ specs.channels = CHANNELS_MONO;
+ specs.format = FORMAT_INVALID;
+
+ std::shared_ptr<IReader> reader = ChannelMapper(*sound, specs).createReader();
+
+ specs.specs = reader->getSpecs();
+ int len;
+ float samplejump = specs.rate / samples_per_second;
+ float min, max, power, overallmax;
+ bool eos;
+
+ overallmax = 0;
+
+ for(int i = 0; i < length; i++)
+ {
+ len = floor(samplejump * (i+1)) - floor(samplejump * i);
+
+ if(*interrupt)
+ return 0;
+
+ aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
+ buf = aBuffer.getBuffer();
+
+ reader->read(len, eos, buf);
+
+ max = min = *buf;
+ power = *buf * *buf;
+ for(int j = 1; j < len; j++)
+ {
+ if(buf[j] < min)
+ min = buf[j];
+ if(buf[j] > max)
+ max = buf[j];
+ power += buf[j] * buf[j];
+ }
+
+ buffer[i * 3] = min;
+ buffer[i * 3 + 1] = max;
+ buffer[i * 3 + 2] = sqrt(power) / len;
+
+ if(overallmax < max)
+ overallmax = max;
+ if(overallmax < -min)
+ overallmax = -min;
+
+ if(eos)
+ {
+ length = i;
+ break;
+ }
+ }
+
+ if(overallmax > 1.0f)
+ {
+ for(int i = 0; i < length * 3; i++)
+ {
+ buffer[i] /= overallmax;
+ }
+ }
+
+ return length;
+}
+
+AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+ try
+ {
+ Sequence* f = dynamic_cast<Sequence *>(sound->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+ std::shared_ptr<IReader> reader = f->createQualityReader();
+ reader->seek(start);
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate);
+ FileWriter::writeReader(reader, writer, length, buffersize);
+
+ return nullptr;
+ }
+ catch(Exception& e)
+ {
+ return e.getMessage().c_str();
+ }
+}
+
+AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+ try
+ {
+ Sequence* f = dynamic_cast<Sequence *>(sound->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+
+ std::vector<std::shared_ptr<IWriter> > writers;
+
+ int channels = specs.channels;
+ specs.channels = AUD_CHANNELS_MONO;
+
+ for(int i = 0; i < channels; i++)
+ {
+ std::stringstream stream;
+ std::string fn = filename;
+ size_t index = fn.find_last_of('.');
+ size_t index_slash = fn.find_last_of('/');
+ size_t index_backslash = fn.find_last_of('\\');
+
+ if((index == std::string::npos) ||
+ ((index < index_slash) && (index_slash != std::string::npos)) ||
+ ((index < index_backslash) && (index_backslash != std::string::npos)))
+ {
+ stream << filename << "_" << (i + 1);
+ }
+ else
+ {
+ stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
+ }
+ writers.push_back(FileWriter::createWriter(stream.str(), convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate));
+ }
+
+ std::shared_ptr<IReader> reader = f->createQualityReader();
+ reader->seek(start);
+ FileWriter::writeReader(reader, writers, length, buffersize);
+
+ return nullptr;
+ }
+ catch(Exception& e)
+ {
+ return e.getMessage().c_str();
+ }
+}
+
+AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
+{
+ try
+ {
+ ReadDevice* device = new ReadDevice(convCToDSpec(specs));
+ device->setQuality(true);
+ device->setVolume(volume);
+
+ Sequence* f = dynamic_cast<Sequence*>(sequencer->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+
+ AUD_Handle handle = device->play(f->createQualityReader());
+ if(handle.get())
+ {
+ handle->seek(start);
+ }
+
+ return new AUD_Device(device);
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_initOnce()
+{
+ PluginManager::loadPlugins();
+ NULLDevice::registerPlugin();
+}
+
+AUD_API void AUD_exitOnce()
+{
+}
+
+AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
+{
+ try
+ {
+ std::shared_ptr<IDeviceFactory> factory = DeviceManager::getDeviceFactory(device);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setBufferSize(buffersize);
+ factory->setSpecs(convCToDSpec(specs));
+ auto device = factory->openDevice();
+ DeviceManager::setDevice(device);
+
+ return new AUD_Device(device);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_exit(AUD_Device* device)
+{
+ delete device;
+ DeviceManager::releaseDevice();
+}
+
+
+AUD_API char** AUD_getDeviceNames()
+{
+ std::vector<std::string> v_names = DeviceManager::getAvailableDeviceNames();
+ char** names = (char**) malloc(sizeof(char*) * (v_names.size() + 1));
+
+ for(int i = 0; i < v_names.size(); i++)
+ {
+ std::string name = v_names[i];
+ names[i] = (char*) malloc(sizeof(char) * (name.length() + 1));
+ strcpy(names[i], name.c_str());
+ }
+
+ names[v_names.size()] = nullptr;
+
+ return names;
+}
diff --git a/extern/audaspace/bindings/C/AUD_Special.h b/extern/audaspace/bindings/C/AUD_Special.h
new file mode 100644
index 00000000000..ab79ae915a2
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Special.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns information about a sound.
+ * \param sound The sound to get the info about.
+ * \return The AUD_SoundInfo structure with filled in data.
+ */
+extern AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound);
+
+/**
+ * Reads a sound file into a newly created float buffer.
+ * The sound is therefore bandpassed, rectified and resampled.
+ */
+extern AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, double samplerate,
+ int* length);
+
+/**
+ * Pauses a playing sound after a specific amount of time.
+ * \param handle The handle to the sound.
+ * \param seconds The time in seconds.
+ * \return The silence handle.
+ */
+extern AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds);
+
+/**
+ * Reads a sound into a buffer for drawing at a specific sampling rate.
+ * \param sound The sound to read.
+ * \param buffer The buffer to write to. Must have a size of 3*4*length.
+ * \param length How many samples to read from the sound.
+ * \param samples_per_second How many samples to read per second of the sound.
+ * \return How many samples really have been read. Always <= length.
+ */
+extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt);
+
+/**
+ * Mixes a sound down into a file.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length,
+ unsigned int buffersize, const char* filename,
+ AUD_DeviceSpecs specs, AUD_Container format,
+ AUD_Codec codec, unsigned int bitrate);
+
+/**
+ * Mixes a sound down into multiple files.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to, the channel number and an underscore are added at the beginning.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length,
+ unsigned int buffersize, const char* filename,
+ AUD_DeviceSpecs specs, AUD_Container format,
+ AUD_Codec codec, unsigned int bitrate);
+
+/**
+ * Opens a read device and prepares it for mixdown of the sound scene.
+ * \param specs Output audio specifications.
+ * \param sequencer The sound scene to mix down.
+ * \param volume The overall mixdown volume.
+ * \param start The start time of the mixdown in the sound scene.
+ * \return The read device for the mixdown.
+ */
+extern AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start);
+
+/**
+ * Initializes audio routines (FFMPEG/JACK if it is enabled).
+ */
+extern AUD_API void AUD_initOnce();
+
+/**
+ * Unitinitializes an audio routines.
+ */
+extern AUD_API void AUD_exitOnce();
+
+/**
+ * Initializes an audio device.
+ * \param device The device type that should be used.
+ * \param specs The audio specification to be used.
+ * \param buffersize The buffersize for the device.
+ * \return Whether the device has been initialized.
+ */
+extern AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name);
+
+/**
+ * Unitinitializes an audio device.
+ * \param device The device to free.
+ */
+extern AUD_API void AUD_exit(AUD_Device* device);
+
+/**
+ * Retrieves available devices. Note that all memory returned has to be freed!
+ */
+extern AUD_API char** AUD_getDeviceNames();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_ThreadPool.cpp b/extern/audaspace/bindings/C/AUD_ThreadPool.cpp
new file mode 100644
index 00000000000..f22a904838b
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ThreadPool.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_ThreadPool.h"
+
+AUD_API AUD_ThreadPool* AUD_ThreadPool_create(int nThreads)
+{
+ try
+ {
+ return new AUD_ThreadPool(new ThreadPool(nThreads));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_ThreadPool_free(AUD_ThreadPool* pool)
+{
+ assert(pool);
+ delete pool;
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_ThreadPool.h b/extern/audaspace/bindings/C/AUD_ThreadPool.h
new file mode 100644
index 00000000000..c1b2204a80a
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ThreadPool.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new ThreadPool object.
+* \param nThreads The number of threads of the pool.
+* \return The new ThreadPool object.
+*/
+extern AUD_API AUD_ThreadPool* AUD_ThreadPool_create(int nThreads);
+
+/**
+* Deletes a ThreadPool object.
+* \param threadPool The ThreadPool object to be deleted.
+*/
+extern AUD_API void AUD_ThreadPool_free(AUD_ThreadPool* threadPool);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Types.h b/extern/audaspace/bindings/C/AUD_Types.h
new file mode 100644
index 00000000000..75e4ffae18c
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Types.h
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "Audaspace.h"
+
+#ifdef __cplusplus
+using namespace aud;
+#endif
+
+#ifdef AUD_CAPI_IMPLEMENTATION
+#include "ISound.h"
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "sequence/SequenceEntry.h"
+#include "fx/PlaybackManager.h"
+#include "fx/DynamicMusic.h"
+#include "fx/Source.h"
+#include "util/ThreadPool.h"
+#ifdef WITH_CONVOLUTION
+#include "fx/ImpulseResponse.h"
+#include "fx/HRTF.h"
+#endif
+
+typedef std::shared_ptr<aud::ISound> AUD_Sound;
+typedef std::shared_ptr<aud::IHandle> AUD_Handle;
+typedef std::shared_ptr<aud::IDevice> AUD_Device;
+typedef std::shared_ptr<aud::SequenceEntry> AUD_SequenceEntry;
+typedef std::shared_ptr<aud::PlaybackManager> AUD_PlaybackManager;
+typedef std::shared_ptr<aud::DynamicMusic> AUD_DynamicMusic;
+typedef std::shared_ptr<aud::ThreadPool> AUD_ThreadPool;
+typedef std::shared_ptr<aud::Source> AUD_Source;
+#ifdef WITH_CONVOLUTION
+typedef std::shared_ptr<aud::ImpulseResponse> AUD_ImpulseResponse;
+typedef std::shared_ptr<aud::HRTF> AUD_HRTF;
+#endif
+#else
+typedef void AUD_Sound;
+typedef void AUD_Handle;
+typedef void AUD_Device;
+typedef void AUD_SequenceEntry;
+typedef void AUD_PlaybackManager;
+typedef void AUD_DynamicMusic;
+typedef void AUD_ThreadPool;
+typedef void AUD_Source;
+#ifdef WITH_CONVOLUTION
+typedef void AUD_ImpulseResponse;
+typedef void AUD_HRTF;
+#endif
+#endif
+
+/// Container formats for writers.
+typedef enum
+{
+ AUD_CONTAINER_INVALID = 0,
+ AUD_CONTAINER_AC3,
+ AUD_CONTAINER_FLAC,
+ AUD_CONTAINER_MATROSKA,
+ AUD_CONTAINER_MP2,
+ AUD_CONTAINER_MP3,
+ AUD_CONTAINER_OGG,
+ AUD_CONTAINER_WAV
+} AUD_Container;
+
+/// Audio codecs for writers.
+typedef enum
+{
+ AUD_CODEC_INVALID = 0,
+ AUD_CODEC_AAC,
+ AUD_CODEC_AC3,
+ AUD_CODEC_FLAC,
+ AUD_CODEC_MP2,
+ AUD_CODEC_MP3,
+ AUD_CODEC_PCM,
+ AUD_CODEC_VORBIS,
+ AUD_CODEC_OPUS
+} AUD_Codec;
+
+/**
+ * The format of a sample.
+ * The last 4 bit save the byte count of the format.
+ */
+typedef enum
+{
+ AUD_FORMAT_INVALID = 0x00, /// Invalid sample format.
+ AUD_FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
+ AUD_FORMAT_S16 = 0x12, /// 2 byte signed integer.
+ AUD_FORMAT_S24 = 0x13, /// 3 byte signed integer.
+ AUD_FORMAT_S32 = 0x14, /// 4 byte signed integer.
+ AUD_FORMAT_FLOAT32 = 0x24, /// 4 byte float.
+ AUD_FORMAT_FLOAT64 = 0x28 /// 8 byte float.
+} AUD_SampleFormat;
+
+/// The channel count.
+typedef enum
+{
+ AUD_CHANNELS_INVALID = 0, /// Invalid channel count.
+ AUD_CHANNELS_MONO = 1, /// Mono.
+ AUD_CHANNELS_STEREO = 2, /// Stereo.
+ AUD_CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
+ AUD_CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
+ AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
+ AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
+ AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
+ AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
+} AUD_Channels;
+
+/**
+ * The sample rate tells how many samples are played back within one second.
+ * Some exotic formats may use other sample rates than provided here.
+ */
+typedef enum
+{
+ AUD_RATE_INVALID = 0, /// Invalid sample rate.
+ AUD_RATE_8000 = 8000, /// 8000 Hz.
+ AUD_RATE_16000 = 16000, /// 16000 Hz.
+ AUD_RATE_11025 = 11025, /// 11025 Hz.
+ AUD_RATE_22050 = 22050, /// 22050 Hz.
+ AUD_RATE_32000 = 32000, /// 32000 Hz.
+ AUD_RATE_44100 = 44100, /// 44100 Hz.
+ AUD_RATE_48000 = 48000, /// 48000 Hz.
+ AUD_RATE_88200 = 88200, /// 88200 Hz.
+ AUD_RATE_96000 = 96000, /// 96000 Hz.
+ AUD_RATE_192000 = 192000 /// 192000 Hz.
+} AUD_DefaultSampleRate;
+
+/// Sample rate type.
+typedef double AUD_SampleRate;
+
+/// Specification of a sound source.
+typedef struct
+{
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+} AUD_Specs;
+
+/// Specification of a sound device.
+typedef struct
+{
+ /// Sample format.
+ AUD_SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+ };
+ AUD_Specs specs;
+ };
+} AUD_DeviceSpecs;
+
+/// Sound information structure.
+typedef struct
+{
+ AUD_Specs specs;
+ float length;
+} AUD_SoundInfo;
diff --git a/extern/audaspace/bindings/doc/conf.py.in b/extern/audaspace/bindings/doc/conf.py.in
new file mode 100644
index 00000000000..e08efbcf7f6
--- /dev/null
+++ b/extern/audaspace/bindings/doc/conf.py.in
@@ -0,0 +1,261 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# audaspace documentation build configuration file, created by
+# sphinx-quickstart on Tue Sep 9 01:48:48 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'audaspace'
+copyright = '2009-2015, Jörg Müller'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@AUDASPACE_VERSION@'
+# The full version, including alpha/beta/rc tags.
+release = '@AUDASPACE_LONG_VERSION@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'audaspacedoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'audaspace.tex', 'audaspace Documentation',
+ 'Jörg Müller', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'audaspace', 'audaspace Documentation',
+ ['Jörg Müller'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'audaspace', 'audaspace Documentation',
+ 'Jörg Müller', 'audaspace', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/extern/audaspace/bindings/doc/device.rst b/extern/audaspace/bindings/doc/device.rst
new file mode 100644
index 00000000000..fd6b334022c
--- /dev/null
+++ b/extern/audaspace/bindings/doc/device.rst
@@ -0,0 +1,7 @@
+Device
+======
+
+.. currentmodule:: aud
+.. autoclass:: Device
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/handle.rst b/extern/audaspace/bindings/doc/handle.rst
new file mode 100644
index 00000000000..aceedbca3a6
--- /dev/null
+++ b/extern/audaspace/bindings/doc/handle.rst
@@ -0,0 +1,7 @@
+Handle
+======
+
+.. currentmodule:: aud
+.. autoclass:: Handle
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/index.rst b/extern/audaspace/bindings/doc/index.rst
new file mode 100644
index 00000000000..b8a26822949
--- /dev/null
+++ b/extern/audaspace/bindings/doc/index.rst
@@ -0,0 +1,35 @@
+.. audaspace documentation master file, created by
+ sphinx-quickstart on Tue Sep 9 01:48:48 2014.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to audaspace's documentation!
+=====================================
+
+.. automodule:: aud
+
+This documentation is valid for both the Python and C bindings of audaspace. If you are looking for installation instructions check the `C++ API documentation <../index.html>`_. As C is not an object oriented language everything is accessible via functions where the first paramter is always the object. For methods these are named as ``AUD_ClassName_method()`` and properties are accessed via ``AUD_ClassName_property_get/set()``. Python users simply ``import aud`` to access the library.
+
+.. toctree::
+ :maxdepth: 2
+
+ tutorials
+
+Classes:
+
+.. toctree::
+ :maxdepth: 2
+
+ device
+ sound
+ handle
+ sequence
+ sequence_entry
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/extern/audaspace/bindings/doc/sequence.rst b/extern/audaspace/bindings/doc/sequence.rst
new file mode 100644
index 00000000000..16fcb00f4dc
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sequence.rst
@@ -0,0 +1,7 @@
+Sequence
+========
+
+.. currentmodule:: aud
+.. autoclass:: Sequence
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/sequence_entry.rst b/extern/audaspace/bindings/doc/sequence_entry.rst
new file mode 100644
index 00000000000..0a3d83388e9
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sequence_entry.rst
@@ -0,0 +1,7 @@
+Sequence Entry
+==============
+
+.. currentmodule:: aud
+.. autoclass:: SequenceEntry
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/sound.rst b/extern/audaspace/bindings/doc/sound.rst
new file mode 100644
index 00000000000..2f14721cf3a
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sound.rst
@@ -0,0 +1,7 @@
+Sound
+=====
+
+.. currentmodule:: aud
+.. autoclass:: Sound
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/tutorials.rst b/extern/audaspace/bindings/doc/tutorials.rst
new file mode 100644
index 00000000000..55f51d9ee2f
--- /dev/null
+++ b/extern/audaspace/bindings/doc/tutorials.rst
@@ -0,0 +1,166 @@
+Tutorials
+=========
+
+Introduction
+------------
+
+The C and Python binding for audaspace were designed with simplicity in mind. This means however that to use the full capabilities of audaspace, there is no way around the C++ library.
+
+Simple Demo
+-----------
+
+The **simple.py** example program contains all the basic building blocks for an application using audaspace. These building blocks are basically the classes :class:`aud.Device`, :class:`aud.Sound` and :class:`aud.Handle`.
+
+We start with importing :mod:`aud` and :mod:`time` as the modules we need for our simple example.
+
+.. code-block:: python
+
+ #!/usr/bin/python
+ import aud, time
+
+The first step now is to open an output device and this can simply be done by allocating a :class:`aud.Device` object.
+
+.. code-block:: python
+
+ device = aud.Device()
+
+To create a sound we can choose to load one from a :func:`aud.Sound.file`, or we use one of our signal generators. We decide to do the latter and create a :func:`aud.Sound.sine` signal with a frequency of 440 Hz.
+
+.. code-block:: python
+
+ sine = aud.Sound.sine(440)
+
+.. note:: At this point nothing is playing back yet, :class:`aud.Sound` objects are just descriptions of sounds.
+
+However instead of a sine wave, we would like to have a square wave to produce a more retro gaming sound. We could of course use the :func:`aud.Sound.square` generator instead of sine, but we want to show how to apply effects, so we apply a :func:`aud.Sound.threshold` which makes a square wave out of our sine too, even if less efficient than directly generating the square wave.
+
+.. code-block:: python
+
+ square = sine.threshold()
+
+.. note:: The :class:`aud.Sound` class offers generator and effect functions.
+
+The we can play our sound by calling the :func:`aud.Device.play` method of our device. This method returns a :class:`aud.Handle` which is used to control the playback of the sound.
+
+.. code-block:: python
+
+ handle = device.play(square)
+
+Now if we do nothing else anymore the application will quit immediately, so we won't hear much of our square wave, so we decide to wait for three seconds before quitting the application by calling :func:`time.sleep`.
+
+.. code-block:: python
+
+ time.sleep(3)
+
+Audioplayer
+-----------
+
+Now that we know the basics of audaspace, we can build our own music player easily by just slightly changing the previous program. The **player.py** example does exactly that, let's have a short look at the differences:
+
+Instead of creating a sine signal and thresholding it, we in fact use the :func:`aud.Sound.file` function to load a sound from a file. The filename we pass is the first command line argument our application got.
+
+.. code-block:: python
+
+ sound = aud.Sound.file(sys.argv[1])
+
+When the sound gets played back we now want to wait until the whole file has been played, so we use the :data:`aud.Handle.status` property to determine whether the sound finished playing.
+
+.. code-block:: python
+
+ while handle.status:
+ time.sleep(0.1)
+
+We don't make any error checks if the user actually added a command line argument. As an exercise you could extend this program to play any number of command line supplied files in sequence.
+
+Siren
+-----
+
+Let's get a little bit more complex. The **siren.py** example plays a generated siren sound that circles around your head. Depending on how many speakers you have and if the output device used supports the speaker setup, you will hear this effect. With stereo speakers you should at least hear some left-right-panning.
+
+We start off again with importing the modules we need and we also define some properties of our siren sound. We want it to consist of two sine sounds with different frequencies. We define a length for the sine sounds and how long a fade in/out should take. We also know already how to open a device.
+
+.. code-block:: python
+
+ #!/usr/bin/python
+ import aud, math, time
+ length = 0.5
+ fadelength = 0.05
+
+ device = aud.Device()
+
+The next thing to do is to define our sine waves and apply all the required effects. As each of the effect functions returns the corresponding sound, we can easily chain those calls together.
+
+.. code-block:: python
+
+ high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+ low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+
+The next step is to connect the two sines, which we do using the :func:`aud.Sound.join` function.
+
+.. code-block:: python
+
+ sound = high.join(low)
+
+The generated siren sound can now be played back and what we also do is to loop it. Therefore we set the :data:`aud.Handle.loop_count` to a negative value to loop forever.
+
+.. code-block:: python
+
+ handle = device.play(sound)
+ handle.loop_count = -1
+
+Now we use some timing code to make sure our demo runs for 10 seconds, but we also use the time to update the location of our playing sound, with the :data:`aud.Handle.location` property, which is a three dimensional vector. The trigonometic calculation based on the running time of the program keeps the sound on the XZ plane letting it follow a circle around us.
+
+.. code-block:: python
+
+ start = time.time()
+
+ while time.time() - start < 10:
+ angle = time.time() - start
+
+ handle.location = [math.sin(angle), 0, -math.cos(angle)]
+
+As an exercise you could try to let the sound come from the far left and go to the far right and a little bit in front of you within the 10 second runtime of the program. With this change you should be able to hear the volume of the sound change, depending on how far it is away from you. Updating the :data:`aud.Handle.velocity` property properly also enables the doppler effect. Compare your solution to the **siren2.py** demo.
+
+Tetris
+------
+
+The **tetris.py** demo application shows an even more complex application which generates retro tetris music. Looking at the source code there should be nothing new here, again the functions used from audaspace are the same as in the previous examples. In the :func:`parseNote` function all single notes get joined which leads to a very long chain of sounds. If you think of :func:`aud.Sound.join` as a function that creates a binary tree with the two joined sounds as leaves then the :func:`parseNote` function creates a very unbalanced tree.
+
+Insted we could rewrite the code to use two other classes: :class:`aud.Sequence` and :class:`aud.SequenceEntry` to sequence the notes. The **tetris2.py** application does exactly that. Before the while loop we add a variable that stores the current position in the score and create a new :class:`aud.Sequence` object.
+
+.. code-block:: python
+
+ position = 0
+ sequence = aud.Sequence()
+
+Then in the loop we can create the note simply by chaining the :func:`aud.Sound.square` generator and :func:`aud.Sound.fadein` and :func:`aud.Sound.fadeout` effects.
+
+.. code-block:: python
+
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+Now instead of using :func:`aud.Sound.limit` and :func:`aud.Sound.join` we simply add the sound to the sequence.
+
+.. code-block:: python
+
+ entry = sequence.add(note, position, position + length, 0)
+
+The entry returned from the :func:`aud.Sequence.add` function is an object of the :class:`aud.SequenceEntry` class. We can use this entry to mute the note in case it's actually a pause.
+
+.. code-block:: python
+
+ if char == 'p':
+ entry.muted = True
+
+Lastly we have to update our position variable.
+
+.. code-block:: python
+
+ position += length
+
+Now in **tetris2.py** we used the :data:`aud.SequenceEntry.muted` property to show how the :class:`aud.SequenceEntry` class can be used, but it would actually be smarter to not even create a note for pauses and just skip them. You can try to implement this as an exercise and then check out the solution in **tetris3.py**.
+
+Conclusion
+----------
+
+We introduced all five currently available classes in the audaspace Python API. Of course all classes offer a lot more functions than have been used in these demo applications, check out the specific class documentation for more details.
diff --git a/extern/audaspace/bindings/python/PyAPI.cpp b/extern/audaspace/bindings/python/PyAPI.cpp
new file mode 100644
index 00000000000..cceadbc0992
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyAPI.cpp
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PyAPI.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+#include "PySequenceEntry.h"
+#include "PySequence.h"
+#include "PyPlaybackManager.h"
+#include "PyDynamicMusic.h"
+#include "PyThreadPool.h"
+#include "PySource.h"
+
+#ifdef WITH_CONVOLUTION
+#include "PyImpulseResponse.h"
+#include "PyHRTF.h"
+#endif
+
+#include "respec/Specification.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "file/IWriter.h"
+#include "plugin/PluginManager.h"
+#include "sequence/AnimateableProperty.h"
+#include "ISound.h"
+
+#include <memory>
+
+#include <structmember.h>
+
+using namespace aud;
+
+// ====================================================================
+
+#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
+
+// ====================================================================
+
+extern PyObject* AUDError;
+PyObject* AUDError = nullptr;
+
+// ====================================================================
+
+PyDoc_STRVAR(M_aud_doc,
+ "Audaspace (pronounced \"outer space\") is a high level audio library.");
+
+static struct PyModuleDef audmodule = {
+ PyModuleDef_HEAD_INIT,
+ "aud", /* name of module */
+ M_aud_doc, /* module documentation */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ nullptr, nullptr, nullptr, nullptr, nullptr
+};
+
+PyMODINIT_FUNC
+PyInit_aud()
+{
+ PyObject* module;
+
+ PluginManager::loadPlugins();
+
+ if(!initializeSound())
+ return nullptr;
+
+ if(!initializeDevice())
+ return nullptr;
+
+ if(!initializeHandle())
+ return nullptr;
+
+ if(!initializeSequenceEntry())
+ return nullptr;
+
+ if(!initializeSequence())
+ return nullptr;
+
+ if(!initializeDynamicMusic())
+ return nullptr;
+
+ if(!initializePlaybackManager())
+ return nullptr;
+
+ if(!initializeThreadPool())
+ return nullptr;
+
+ if(!initializeSource())
+ return nullptr;
+
+#ifdef WITH_CONVOLUTION
+ if(!initializeImpulseResponse())
+ return nullptr;
+
+ if(!initializeHRTF())
+ return nullptr;
+#endif
+
+ module = PyModule_Create(&audmodule);
+ if(module == nullptr)
+ return nullptr;
+
+ addSoundToModule(module);
+ addHandleToModule(module);
+ addDeviceToModule(module);
+ addSequenceEntryToModule(module);
+ addSequenceToModule(module);
+ addDynamicMusicToModule(module);
+ addPlaybackManagerToModule(module);
+ addThreadPoolToModule(module);
+ addSourceToModule(module);
+
+#ifdef WITH_CONVOLUTION
+ addImpulseResponseToModule(module);
+ addHRTFToModule(module);
+#endif
+
+ AUDError = PyErr_NewException("aud.error", nullptr, nullptr);
+ Py_INCREF(AUDError);
+ PyModule_AddObject(module, "error", AUDError);
+
+ // animatable property type constants
+ PY_MODULE_ADD_CONSTANT(module, AP_VOLUME);
+ PY_MODULE_ADD_CONSTANT(module, AP_PANNING);
+ PY_MODULE_ADD_CONSTANT(module, AP_PITCH);
+ PY_MODULE_ADD_CONSTANT(module, AP_LOCATION);
+ PY_MODULE_ADD_CONSTANT(module, AP_ORIENTATION);
+ // channels constants
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_MONO);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_STEREO);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_STEREO_LFE);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND4);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND5);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND51);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND61);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND71);
+ // codec constants
+ PY_MODULE_ADD_CONSTANT(module, CODEC_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_AAC);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_AC3);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_FLAC);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_MP2);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_MP3);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_PCM);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_VORBIS);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_OPUS);
+ // container constants
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_AC3);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_FLAC);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MATROSKA);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MP2);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MP3);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_OGG);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_WAV);
+ // distance model constants
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVERSE);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVERSE_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_LINEAR);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_LINEAR_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVALID);
+ // format constants
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_FLOAT32);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_FLOAT64);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S16);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S24);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S32);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_U8);
+ // rate constants
+ PY_MODULE_ADD_CONSTANT(module, RATE_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, RATE_8000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_16000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_11025);
+ PY_MODULE_ADD_CONSTANT(module, RATE_22050);
+ PY_MODULE_ADD_CONSTANT(module, RATE_32000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_44100);
+ PY_MODULE_ADD_CONSTANT(module, RATE_48000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_88200);
+ PY_MODULE_ADD_CONSTANT(module, RATE_96000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_192000);
+ // status constants
+ PY_MODULE_ADD_CONSTANT(module, STATUS_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_PAUSED);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_PLAYING);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_STOPPED);
+
+ return module;
+}
+
+AUD_API PyObject* AUD_getPythonSound(void* sound)
+{
+ if(sound)
+ {
+ Sound* object = (Sound*) Sound_empty();
+ if(object)
+ {
+ object->sound = new std::shared_ptr<ISound>(*reinterpret_cast<std::shared_ptr<ISound>*>(sound));
+ return (PyObject *) object;
+ }
+ }
+
+ return nullptr;
+}
+
+AUD_API void* AUD_getSoundFromPython(PyObject* object)
+{
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ return new std::shared_ptr<ISound>(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound));
+}
diff --git a/extern/audaspace/bindings/python/PyAPI.h b/extern/audaspace/bindings/python/PyAPI.h
new file mode 100644
index 00000000000..a413b4813d6
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyAPI.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyMODINIT_FUNC
+PyInit_aud();
+
+/**
+ * Retrieves the python factory of a sound.
+ * \param sound The sound factory.
+ * \return The python factory.
+ */
+extern AUD_API PyObject* AUD_getPythonSound(void* sound);
+
+/**
+ * Retrieves the sound factory of a python factory.
+ * \param sound The python factory.
+ * \return The sound factory.
+ */
+extern AUD_API void* AUD_getSoundFromPython(PyObject* object);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/python/PyDevice.cpp b/extern/audaspace/bindings/python/PyDevice.cpp
new file mode 100644
index 00000000000..a6beef57d83
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDevice.cpp
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PyDevice.h"
+
+#include "PySound.h"
+#include "PyHandle.h"
+
+#include "Exception.h"
+#include "devices/IDevice.h"
+#include "devices/I3DDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+
+#include <structmember.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+static const char* device_not_3d_error = "Device is not a 3D device!";
+
+// ====================================================================
+
+static void
+Device_dealloc(Device* self)
+{
+ if(self->device)
+ delete reinterpret_cast<std::shared_ptr<IDevice>*>(self->device);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Device_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Device* self;
+
+ static const char* kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", nullptr};
+ const char* device = nullptr;
+ double rate = RATE_48000;
+ int channels = CHANNELS_STEREO;
+ int format = FORMAT_FLOAT32;
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ const char* name = "";
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|sdiiis:Device", const_cast<char**>(kwlist),
+ &device, &rate, &channels, &format, &buffersize, &name))
+ return nullptr;
+
+ if(buffersize < 128)
+ {
+ PyErr_SetString(PyExc_ValueError, "buffer_size must be at least 128!");
+ return nullptr;
+ }
+
+ self = (Device*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ DeviceSpecs specs;
+ specs.channels = (Channels)channels;
+ specs.format = (SampleFormat)format;
+ specs.rate = (SampleRate)rate;
+
+ self->device = nullptr;
+
+ try
+ {
+ if(!device)
+ {
+ auto dev = DeviceManager::getDevice();
+ if(!dev)
+ {
+ DeviceManager::openDefaultDevice();
+ dev = DeviceManager::getDevice();
+ }
+ self->device = new std::shared_ptr<IDevice>(dev);
+ }
+ else
+ {
+ std::shared_ptr<IDeviceFactory> factory;
+ if(!*device)
+ factory = DeviceManager::getDefaultDeviceFactory();
+ else
+ factory = DeviceManager::getDeviceFactory(device);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setSpecs(specs);
+ factory->setBufferSize(buffersize);
+ self->device = new std::shared_ptr<IDevice>(factory->openDevice());
+ }
+ }
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+
+ if(!self->device)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Unsupported device type!");
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Device_lock_doc,
+ "lock()\n\n"
+ "Locks the device so that it's guaranteed, that no samples are "
+ "read from the streams until :meth:`unlock` is called.\n"
+ "This is useful if you want to do start/stop/pause/resume some "
+ "sounds at the same time.\n\n"
+ ".. note:: The device has to be unlocked as often as locked to be "
+ "able to continue playback.\n\n"
+ ".. warning:: Make sure the time between locking and unlocking is "
+ "as short as possible to avoid clicks.");
+
+static PyObject *
+Device_lock(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->lock();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_play_doc,
+ "play(sound, keep=False)\n\n"
+ "Plays a sound.\n\n"
+ ":arg sound: The sound to play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg keep: See :attr:`Handle.keep`.\n"
+ ":type keep: bool\n"
+ ":return: The playback handle with which playback can be "
+ "controlled with.\n"
+ ":rtype: :class:`Handle`");
+
+static PyObject *
+Device_play(Device* self, PyObject* args, PyObject* kwds)
+{
+ PyObject* object;
+ PyObject* keepo = nullptr;
+
+ bool keep = false;
+
+ static const char* kwlist[] = {"sound", "keep", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ if(keepo != nullptr)
+ {
+ if(!PyBool_Check(keepo))
+ {
+ PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+ return nullptr;
+ }
+
+ keep = keepo == Py_True;
+ }
+
+ Handle* handle;
+
+ handle = (Handle*)Handle_empty();
+ if(handle != nullptr)
+ {
+ try
+ {
+ handle->handle = new std::shared_ptr<IHandle>((*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->play(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound), keep));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(handle);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)handle;
+}
+
+PyDoc_STRVAR(M_aud_Device_stopAll_doc,
+ "stopAll()\n\n"
+ "Stops all playing and paused sounds.");
+
+static PyObject *
+Device_stopAll(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->stopAll();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_unlock_doc,
+ "unlock()\n\n"
+ "Unlocks the device after a lock call, see :meth:`lock` for "
+ "details.");
+
+static PyObject *
+Device_unlock(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->unlock();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Device_methods[] = {
+ {"lock", (PyCFunction)Device_lock, METH_NOARGS,
+ M_aud_Device_lock_doc
+ },
+ {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Device_play_doc
+ },
+ {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS,
+ M_aud_Device_stopAll_doc
+ },
+ {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
+ M_aud_Device_unlock_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Device_channels_doc,
+ "The channel count of the device.");
+
+static PyObject *
+Device_get_channels(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("i", specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_distance_model_doc,
+ "The distance model of the device.\n\n"
+ ".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
+
+static PyObject *
+Device_get_distance_model(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("i", int(device->getDistanceModel()));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_distance_model(Device* self, PyObject* args, void* nothing)
+{
+ int model;
+
+ if(!PyArg_Parse(args, "i:distance_model", &model))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setDistanceModel(DistanceModel(model));
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
+ "The doppler factor of the device.\n"
+ "This factor is a scaling factor for the velocity vectors in "
+ "doppler calculation. So a value bigger than 1 will exaggerate "
+ "the effect as it raises the velocity.");
+
+static PyObject *
+Device_get_doppler_factor(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("f", device->getDopplerFactor());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_doppler_factor(Device* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:doppler_factor", &factor))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setDopplerFactor(factor);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_format_doc,
+ "The native sample format of the device.");
+
+static PyObject *
+Device_get_format(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("i", specs.format);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_location_doc,
+ "The listeners's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_location(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 v = device->getListenerLocation();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_location(Device* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 location(x, y, z);
+ device->setListenerLocation(location);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
+ "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Device_get_listener_orientation(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Quaternion o = device->getListenerOrientation();
+ return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_orientation(Device* self, PyObject* args, void* nothing)
+{
+ float w, x, y, z;
+
+ if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Quaternion orientation(w, x, y, z);
+ device->setListenerOrientation(orientation);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
+ "The listener's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_velocity(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 v = device->getListenerVelocity();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_velocity(Device* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 velocity(x, y, z);
+ device->setListenerVelocity(velocity);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_rate_doc,
+ "The sampling rate of the device in Hz.");
+
+static PyObject *
+Device_get_rate(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("d", specs.rate);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
+ "The speed of sound of the device.\n"
+ "The speed of sound in air is typically 343.3 m/s.");
+
+static PyObject *
+Device_get_speed_of_sound(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSpeedOfSound());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_speed_of_sound(Device* self, PyObject* args, void* nothing)
+{
+ float speed;
+
+ if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setSpeedOfSound(speed);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_volume_doc,
+ "The overall volume of the device.");
+
+static PyObject *
+Device_get_volume(Device* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getVolume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_volume(Device* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->setVolume(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+static PyGetSetDef Device_properties[] = {
+ {(char*)"channels", (getter)Device_get_channels, nullptr,
+ M_aud_Device_channels_doc, nullptr },
+ {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
+ M_aud_Device_distance_model_doc, nullptr },
+ {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
+ M_aud_Device_doppler_factor_doc, nullptr },
+ {(char*)"format", (getter)Device_get_format, nullptr,
+ M_aud_Device_format_doc, nullptr },
+ {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
+ M_aud_Device_listener_location_doc, nullptr },
+ {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
+ M_aud_Device_listener_orientation_doc, nullptr },
+ {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
+ M_aud_Device_listener_velocity_doc, nullptr },
+ {(char*)"rate", (getter)Device_get_rate, nullptr,
+ M_aud_Device_rate_doc, nullptr },
+ {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
+ M_aud_Device_speed_of_sound_doc, nullptr },
+ {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
+ M_aud_Device_volume_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Device_doc,
+ "Device objects represent an audio output backend like OpenAL or "
+ "SDL, but might also represent a file output or RAM buffer "
+ "output.");
+
+static PyTypeObject DeviceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Device", /* tp_name */
+ sizeof(Device), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Device_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Device_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Device_methods, /* tp_methods */
+ 0, /* tp_members */
+ Device_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Device_new, /* tp_new */
+};
+
+AUD_API PyObject* Device_empty()
+{
+ return DeviceType.tp_alloc(&DeviceType, 0);
+}
+
+
+AUD_API Device* checkDevice(PyObject* device)
+{
+ if(!PyObject_TypeCheck(device, &DeviceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Device!");
+ return nullptr;
+ }
+
+ return (Device*)device;
+}
+
+
+bool initializeDevice()
+{
+ return PyType_Ready(&DeviceType) >= 0;
+}
+
+
+void addDeviceToModule(PyObject* module)
+{
+ Py_INCREF(&DeviceType);
+ PyModule_AddObject(module, "Device", (PyObject *)&DeviceType);
+}
diff --git a/extern/audaspace/bindings/python/PyDevice.h b/extern/audaspace/bindings/python/PyDevice.h
new file mode 100644
index 00000000000..610b5b4cd23
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDevice.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_IDevice;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_IDevice* device;
+} Device;
+
+extern AUD_API PyObject* Device_empty();
+extern AUD_API Device* checkDevice(PyObject* device);
+
+bool initializeDevice();
+void addDeviceToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PyDynamicMusic.cpp b/extern/audaspace/bindings/python/PyDynamicMusic.cpp
new file mode 100644
index 00000000000..d49f73737c2
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDynamicMusic.cpp
@@ -0,0 +1,467 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PyDynamicMusic.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+
+#include "Exception.h"
+#include "fx/DynamicMusic.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+DynamicMusic_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ DynamicMusicP* self = (DynamicMusicP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:device", &object))
+ return nullptr;
+ Device* device = checkDevice(object);
+
+ try
+ {
+ self->dynamicMusic = new std::shared_ptr<aud::DynamicMusic>(new aud::DynamicMusic(*reinterpret_cast<std::shared_ptr<aud::IDevice>*>(device->device)));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+DynamicMusic_dealloc(DynamicMusicP* self)
+{
+ if(self->dynamicMusic)
+ delete reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_addScene_doc,
+ "addScene(scene)\n\n"
+ "Adds a new scene.\n\n"
+ ":arg scene: The scene sound.\n"
+ ":type scene: :class:`Sound`\n"
+ ":return: The new scene id.\n"
+ ":rtype: int");
+
+static PyObject *
+DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
+{
+ PyObject* object;
+ if(!PyArg_Parse(args, "O:sound", &object))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addScene(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound)));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_addTransition_doc,
+ "addTransition(ini, end, transition)\n\n"
+ "Adds a new scene.\n\n"
+ ":arg ini: the initial scene foor the transition.\n"
+ ":type ini: int\n"
+ ":arg end: The final scene for the transition.\n"
+ ":type end: int\n"
+ ":arg transition: The transition sound.\n"
+ ":type transition: :class:`Sound`\n"
+ ":return: false if the ini or end scenes don't exist, true othrwise.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
+{
+ PyObject* object;
+ int ini, end;
+ if(!PyArg_ParseTuple(args, "iiO:sound", &ini, &end, &object))
+ return nullptr;
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addTransition(ini, end, *reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound));
+ Py_RETURN_NONE;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_resume_doc,
+ "resume()\n\n"
+ "Resumes playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_resume(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->resume());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_pause_doc,
+ "pause()\n\n"
+ "Pauses playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_pause(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->pause());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_stop_doc,
+ "stop()\n\n"
+ "Stops playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n");
+
+static PyObject *
+DynamicMusic_stop(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->stop());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef DynamicMusic_methods[] = {
+ { "addScene", (PyCFunction)DynamicMusic_addScene, METH_O,
+ M_aud_DynamicMusic_addScene_doc
+ },
+ { "addTransition", (PyCFunction)DynamicMusic_addTransition, METH_VARARGS,
+ M_aud_DynamicMusic_addTransition_doc
+ },
+ { "resume", (PyCFunction)DynamicMusic_resume, METH_NOARGS,
+ M_aud_DynamicMusic_resume_doc
+ },
+ { "pause", (PyCFunction)DynamicMusic_pause, METH_NOARGS,
+ M_aud_DynamicMusic_pause_doc
+ },
+ { "stop", (PyCFunction)DynamicMusic_stop, METH_NOARGS,
+ M_aud_DynamicMusic_stop_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+/////////////////////////////////////////////////////
+
+PyDoc_STRVAR(M_aud_DynamicMusic_status_doc,
+ "Whether the scene is playing, paused or stopped (=invalid).");
+
+static PyObject *
+DynamicMusic_get_status(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getStatus());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_position_doc,
+ "The playback position of the scene in seconds.");
+
+static int
+DynamicMusic_set_position(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float position;
+
+ if(!PyArg_Parse(args, "f:position", &position))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->seek(position))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't seek the sound!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_position(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getPosition());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_fadeTime_doc,
+ "The length in seconds of the crossfade transition");
+
+static int
+DynamicMusic_set_fadeTime(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float fadeTime;
+
+ if(!PyArg_Parse(args, "f:fadeTime", &fadeTime))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setFadeTime(fadeTime);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_fadeTime(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getFadeTime());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_scene_doc,
+ "The current scene");
+
+static int
+DynamicMusic_set_scene(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ int scene;
+
+ if(!PyArg_Parse(args, "i:scene", &scene))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->changeScene(scene))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't change the scene!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_scene(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getScene());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_volume_doc,
+ "The volume of the scene.");
+
+static int
+DynamicMusic_set_volume(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setVolume(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't change the volume!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_volume(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getVolume());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef DynamicMusic_properties[] = {
+ { (char*)"status", (getter)DynamicMusic_get_status, nullptr,
+ M_aud_DynamicMusic_status_doc, nullptr },
+ { (char*)"position", (getter)DynamicMusic_get_position, (setter)DynamicMusic_set_position,
+ M_aud_DynamicMusic_position_doc, nullptr },
+ { (char*)"fadeTime", (getter)DynamicMusic_get_fadeTime, (setter)DynamicMusic_set_fadeTime,
+ M_aud_DynamicMusic_fadeTime_doc, nullptr },
+ { (char*)"scene", (getter)DynamicMusic_get_scene, (setter)DynamicMusic_set_scene,
+ M_aud_DynamicMusic_scene_doc, nullptr },
+ { (char*)"volume", (getter)DynamicMusic_get_volume, (setter)DynamicMusic_set_volume,
+ M_aud_DynamicMusic_volume_doc, nullptr },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_DynamicMusic_doc,
+ "The DynamicMusic object allows to play music depending on a current scene, scene changes are managed by the class, with the possibility of custom transitions.\n"
+ "The default transition is a crossfade effect, and the default scene is silent and has id 0");
+
+PyTypeObject DynamicMusicType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.DynamicMusic", /* tp_name */
+ sizeof(DynamicMusicP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)DynamicMusic_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_DynamicMusic_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ DynamicMusic_methods, /* tp_methods */
+ 0, /* tp_members */
+ DynamicMusic_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ DynamicMusic_new, /* tp_new */
+};
+
+AUD_API PyObject* DynamicMusic_empty()
+{
+ return DynamicMusicType.tp_alloc(&DynamicMusicType, 0);
+}
+
+
+AUD_API DynamicMusicP* checkDynamicMusic(PyObject* dynamicMusic)
+{
+ if(!PyObject_TypeCheck(dynamicMusic, &DynamicMusicType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type DynamicMusic!");
+ return nullptr;
+ }
+
+ return (DynamicMusicP*)dynamicMusic;
+}
+
+
+bool initializeDynamicMusic()
+{
+ return PyType_Ready(&DynamicMusicType) >= 0;
+}
+
+
+void addDynamicMusicToModule(PyObject* module)
+{
+ Py_INCREF(&DynamicMusicType);
+ PyModule_AddObject(module, "DynamicMusic", (PyObject *)&DynamicMusicType);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyDynamicMusic.h b/extern/audaspace/bindings/python/PyDynamicMusic.h
new file mode 100644
index 00000000000..f19de2d8c75
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDynamicMusic.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_DynamicMusic;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_DynamicMusic* dynamicMusic;
+} DynamicMusicP;
+
+extern AUD_API PyObject* DynamicMusic_empty();
+extern AUD_API DynamicMusicP* checkDynamicMusic(PyObject* dynamicMusic);
+
+bool initializeDynamicMusic();
+void addDynamicMusicToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyHRTF.cpp b/extern/audaspace/bindings/python/PyHRTF.cpp
new file mode 100644
index 00000000000..2a5b6be624f
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHRTF.cpp
@@ -0,0 +1,247 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PyHRTF.h"
+#include "PySound.h"
+
+#include "Exception.h"
+#include "fx/HRTF.h"
+#include "fx/HRTFLoader.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+HRTF_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ HRTFP* self = (HRTFP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(new aud::HRTF());
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+HRTF_dealloc(HRTFP* self)
+{
+ if(self->hrtf)
+ delete reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_HRTF_addImpulseResponse_doc,
+ "addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
+ "Adds a new hrtf to the HRTF object\n\n"
+ ":arg sound: The sound that contains the hrtf.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg azimuth: The azimuth angle of the hrtf.\n"
+ ":type azimuth: float\n"
+ ":arg elevation: The elevation angle of the hrtf.\n"
+ ":type elevation: float\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
+{
+ PyObject* object;
+ float azimuth, elevation;
+
+ if(!PyArg_ParseTuple(args, "Off:hrtf", &object, &azimuth, &elevation))
+ return nullptr;
+
+ Sound* ir = checkSound(object);
+ if(!ir)
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf))->addImpulseResponse(std::make_shared<aud::StreamBuffer>(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(ir->sound)), azimuth, elevation));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_HRTF_loadLeftHrtfSet_doc,
+ "loadLeftHrtfSet(extension, directory)\n\n"
+ "Loads all HRTFs from a directory.\n\n"
+ ":arg extension: The file extension of the hrtfs.\n"
+ ":type extension: string\n"
+ ":arg directory: The path to where the HRTF files are located.\n"
+ ":type extension: string\n"
+ ":return: The loaded :class:`HRTF` object.\n"
+ ":rtype: :class:`HRTF`\n\n");
+
+static PyObject *
+HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
+{
+ const char* dir = nullptr;
+ const char* ext = nullptr;
+
+ if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
+ return nullptr;
+
+ HRTFP* self;
+ self = (HRTFP*)type->tp_alloc(type, 0);
+
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadLeftHRTFs(ext, dir));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_HRTF_loadRightHrtfSet_doc,
+ "loadLeftHrtfSet(extension, directory)\n\n"
+ "Loads all HRTFs from a directory.\n\n"
+ ":arg extension: The file extension of the hrtfs.\n"
+ ":type extension: string\n"
+ ":arg directory: The path to where the HRTF files are located.\n"
+ ":type extension: string\n"
+ ":return: The loaded :class:`HRTF` object.\n"
+ ":rtype: :class:`HRTF`\n\n");
+
+static PyObject *
+HRTF_loadRightHrtfSet(PyTypeObject* type, PyObject* args)
+{
+ const char* dir = nullptr;
+ const char* ext = nullptr;
+
+ if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
+ return nullptr;
+
+ HRTFP* self;
+ self = (HRTFP*)type->tp_alloc(type, 0);
+
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadRightHRTFs(ext, dir));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ return (PyObject *)self;
+}
+
+static PyMethodDef HRTF_methods[] = {
+ { "addImpulseResponseFromSound", (PyCFunction)HRTF_addImpulseResponseFromSound, METH_VARARGS | METH_KEYWORDS,
+ M_aud_HRTF_addImpulseResponse_doc
+ },
+ { "loadLeftHrtfSet", (PyCFunction)HRTF_loadLeftHrtfSet, METH_VARARGS | METH_CLASS,
+ M_aud_HRTF_loadLeftHrtfSet_doc
+ },
+ { "loadRightHrtfSet", (PyCFunction)HRTF_loadRightHrtfSet, METH_VARARGS | METH_CLASS,
+ M_aud_HRTF_loadRightHrtfSet_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_HRTF_doc,
+ "An HRTF object represents a set of head related transfer functions as impulse responses. It's used for binaural sound");
+
+PyTypeObject HRTFType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.HRTF", /* tp_name */
+ sizeof(HRTFP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)HRTF_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_HRTF_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ HRTF_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ HRTF_new, /* tp_new */
+};
+
+AUD_API PyObject* HRTF_empty()
+{
+ return HRTFType.tp_alloc(&HRTFType, 0);
+}
+
+
+AUD_API HRTFP* checkHRTF(PyObject* hrtf)
+{
+ if(!PyObject_TypeCheck(hrtf, &HRTFType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type HRTF!");
+ return nullptr;
+ }
+
+ return (HRTFP*)hrtf;
+}
+
+
+bool initializeHRTF()
+{
+ return PyType_Ready(&HRTFType) >= 0;
+}
+
+
+void addHRTFToModule(PyObject* module)
+{
+ Py_INCREF(&HRTFType);
+ PyModule_AddObject(module, "HRTF", (PyObject *)&HRTFType);
+}
diff --git a/extern/audaspace/bindings/python/PyHRTF.h b/extern/audaspace/bindings/python/PyHRTF.h
new file mode 100644
index 00000000000..0445069929f
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHRTF.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_HRTF;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_HRTF* hrtf;
+} HRTFP;
+
+extern AUD_API PyObject* HRTF_empty();
+extern AUD_API HRTFP* checkHRTF(PyObject* hrtf);
+
+bool initializeHRTF();
+void addHRTFToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyHandle.cpp b/extern/audaspace/bindings/python/PyHandle.cpp
new file mode 100644
index 00000000000..7f7a7660049
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHandle.cpp
@@ -0,0 +1,1126 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PyHandle.h"
+
+#include "devices/IHandle.h"
+#include "devices/I3DHandle.h"
+#include "Exception.h"
+
+#include <memory>
+
+#include <structmember.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+static const char* device_not_3d_error = "Device is not a 3D device!";
+
+static void
+Handle_dealloc(Handle* self)
+{
+ if(self->handle)
+ delete reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_pause_doc,
+ "pause()\n\n"
+ "Pauses playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+Handle_pause(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->pause());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_resume_doc,
+ "resume()\n\n"
+ "Resumes playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+Handle_resume(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->resume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_stop_doc,
+ "stop()\n\n"
+ "Stops playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n"
+ ".. note:: This makes the handle invalid.");
+
+static PyObject *
+Handle_stop(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->stop());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Handle_methods[] = {
+ {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
+ M_aud_Handle_pause_doc
+ },
+ {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
+ M_aud_Handle_resume_doc
+ },
+ {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
+ M_aud_Handle_stop_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
+ "This factor is used for distance based attenuation of the "
+ "source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_attenuation(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getAttenuation());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_attenuation(Handle* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:attenuation", &factor))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setAttenuation(factor))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the attenuation!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
+ "The opening angle of the inner cone of the source. If the cone "
+ "values of a source are set there are two (audible) cones with "
+ "the apex at the :attr:`location` of the source and with infinite "
+ "height, heading in the direction of the source's "
+ ":attr:`orientation`.\n"
+ "In the inner cone the volume is normal. Outside the outer cone "
+ "the volume will be :attr:`cone_volume_outer` and in the area "
+ "between the volume will be interpolated linearly.");
+
+static PyObject *
+Handle_get_cone_angle_inner(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeAngleInner());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_angle_inner(Handle* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeAngleInner(angle))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
+ "The opening angle of the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+Handle_get_cone_angle_outer(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeAngleOuter());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_angle_outer(Handle* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeAngleOuter(angle))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
+ "The volume outside the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+Handle_get_cone_volume_outer(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeVolumeOuter());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_volume_outer(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeVolumeOuter(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
+ "The maximum distance of the source.\n"
+ "If the listener is further away the source volume will be 0.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_distance_maximum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getDistanceMaximum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_distance_maximum(Handle* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_maximum", &distance))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setDistanceMaximum(distance))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
+ "The reference distance of the source.\n"
+ "At this distance the volume will be exactly :attr:`volume`.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_distance_reference(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getDistanceReference());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_distance_reference(Handle* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_reference", &distance))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setDistanceReference(distance))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the reference distance!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_keep_doc,
+ "Whether the sound should be kept paused in the device when its "
+ "end is reached.\n"
+ "This can be used to seek the sound to some position and start "
+ "playback again.\n\n"
+ ".. warning:: If this is set to true and you forget stopping this "
+ "equals a memory leak as the handle exists until the device is "
+ "destroyed.");
+
+static PyObject *
+Handle_get_keep(Handle* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getKeep());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_keep(Handle* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+ return -1;
+ }
+
+ bool keep = args == Py_True;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setKeep(keep))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_location_doc,
+ "The source's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_location(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 v = handle->getLocation();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_location(Handle* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 location(x, y, z);
+ if(handle->setLocation(location))
+ return 0;
+ PyErr_SetString(AUDError, "Location couldn't be set!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
+ "The (remaining) loop count of the sound. A negative value indicates infinity.");
+
+static PyObject *
+Handle_get_loop_count(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getLoopCount());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_loop_count(Handle* self, PyObject* args, void* nothing)
+{
+ int loops;
+
+ if(!PyArg_Parse(args, "i:loop_count", &loops))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setLoopCount(loops))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the loop count!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_orientation_doc,
+ "The source's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Handle_get_orientation(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Quaternion o = handle->getOrientation();
+ return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_orientation(Handle* self, PyObject* args, void* nothing)
+{
+ float w, x, y, z;
+
+ if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Quaternion orientation(w, x, y, z);
+ if(handle->setOrientation(orientation))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the orientation!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_pitch_doc,
+ "The pitch of the sound.");
+
+static PyObject *
+Handle_get_pitch(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPitch());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_pitch(Handle* self, PyObject* args, void* nothing)
+{
+ float pitch;
+
+ if(!PyArg_Parse(args, "f:pitch", &pitch))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setPitch(pitch))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_position_doc,
+ "The playback position of the sound in seconds.");
+
+static PyObject *
+Handle_get_position(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPosition());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_position(Handle* self, PyObject* args, void* nothing)
+{
+ float position;
+
+ if(!PyArg_Parse(args, "f:position", &position))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->seek(position))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't seek the sound!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_relative_doc,
+ "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
+
+static PyObject *
+Handle_get_relative(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return PyBool_FromLong((long)handle->isRelative());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_relative(Handle* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+ return -1;
+ }
+
+ bool relative = (args == Py_True);
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setRelative(relative))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the relativeness!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_status_doc,
+ "Whether the sound is playing, paused or stopped (=invalid).");
+
+static PyObject *
+Handle_get_status(Handle* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getStatus());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_velocity_doc,
+ "The source's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_velocity(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 v = handle->getVelocity();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_velocity(Handle* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 velocity(x, y, z);
+ if(handle->setVelocity(velocity))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the velocity!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_doc,
+ "The volume of the sound.");
+
+static PyObject *
+Handle_get_volume(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getVolume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setVolume(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the sound volume!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
+ "The maximum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_volume_maximum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getVolumeMaximum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume_maximum(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_maximum", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setVolumeMaximum(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
+ "The minimum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_volume_minimum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getVolumeMinimum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume_minimum(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_minimum", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setVolumeMinimum(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyGetSetDef Handle_properties[] = {
+ {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
+ M_aud_Handle_attenuation_doc, nullptr },
+ {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
+ M_aud_Handle_cone_angle_inner_doc, nullptr },
+ {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
+ M_aud_Handle_cone_angle_outer_doc, nullptr },
+ {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
+ M_aud_Handle_cone_volume_outer_doc, nullptr },
+ {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
+ M_aud_Handle_distance_maximum_doc, nullptr },
+ {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
+ M_aud_Handle_distance_reference_doc, nullptr },
+ {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
+ M_aud_Handle_keep_doc, nullptr },
+ {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
+ M_aud_Handle_location_doc, nullptr },
+ {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
+ M_aud_Handle_loop_count_doc, nullptr },
+ {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
+ M_aud_Handle_orientation_doc, nullptr },
+ {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
+ M_aud_Handle_pitch_doc, nullptr },
+ {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
+ M_aud_Handle_position_doc, nullptr },
+ {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
+ M_aud_Handle_relative_doc, nullptr },
+ {(char*)"status", (getter)Handle_get_status, nullptr,
+ M_aud_Handle_status_doc, nullptr },
+ {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
+ M_aud_Handle_velocity_doc, nullptr },
+ {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
+ M_aud_Handle_volume_doc, nullptr },
+ {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
+ M_aud_Handle_volume_maximum_doc, nullptr },
+ {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
+ M_aud_Handle_volume_minimum_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_doc,
+ "Handle objects are playback handles that can be used to control "
+ "playback of a sound. If a sound is played back multiple times "
+ "then there are as many handles.");
+
+static PyTypeObject HandleType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Handle", /* tp_name */
+ sizeof(Handle), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Handle_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Handle_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Handle_methods, /* tp_methods */
+ 0, /* tp_members */
+ Handle_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+
+AUD_API PyObject* Handle_empty()
+{
+ return HandleType.tp_alloc(&HandleType, 0);
+}
+
+
+AUD_API Handle*checkHandle(PyObject* handle)
+{
+ if(!PyObject_TypeCheck(handle, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Handle!");
+ return nullptr;
+ }
+
+ return (Handle*)handle;
+}
+
+
+bool initializeHandle()
+{
+ return PyType_Ready(&HandleType) >= 0;
+}
+
+
+void addHandleToModule(PyObject* module)
+{
+ Py_INCREF(&HandleType);
+ PyModule_AddObject(module, "Handle", (PyObject *)&HandleType);
+}
+
+
diff --git a/extern/audaspace/bindings/python/PyHandle.h b/extern/audaspace/bindings/python/PyHandle.h
new file mode 100644
index 00000000000..95006c88da7
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHandle.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_IHandle;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_IHandle* handle;
+} Handle;
+
+extern AUD_API PyObject* Handle_empty();
+extern AUD_API Handle* checkHandle(PyObject* handle);
+
+bool initializeHandle();
+void addHandleToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PyImpulseResponse.cpp b/extern/audaspace/bindings/python/PyImpulseResponse.cpp
new file mode 100644
index 00000000000..5200c938511
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyImpulseResponse.cpp
@@ -0,0 +1,137 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PyImpulseResponse.h"
+#include "PySound.h"
+
+#include "Exception.h"
+#include "fx/ImpulseResponse.h"
+#include "util/StreamBuffer.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+ImpulseResponse_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ ImpulseResponseP* self = (ImpulseResponseP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:sound", &object))
+ return nullptr;
+ Sound* sound = checkSound(object);
+
+ try
+ {
+ self->impulseResponse = new std::shared_ptr<aud::ImpulseResponse>(new aud::ImpulseResponse(std::make_shared<aud::StreamBuffer>(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound))));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+ImpulseResponse_dealloc(ImpulseResponseP* self)
+{
+ if(self->impulseResponse)
+ delete reinterpret_cast<std::shared_ptr<aud::ImpulseResponse>*>(self->impulseResponse);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef ImpulseResponse_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_ImpulseResponse_doc,
+ "An ImpulseResponse object represents a filter with which to convolve a sound.");
+
+PyTypeObject ImpulseResponseType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.ImpulseResponse", /* tp_name */
+ sizeof(ImpulseResponseP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)ImpulseResponse_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_ImpulseResponse_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ ImpulseResponse_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ImpulseResponse_new, /* tp_new */
+};
+
+AUD_API PyObject* ImpulseResponse_empty()
+{
+ return ImpulseResponseType.tp_alloc(&ImpulseResponseType, 0);
+}
+
+
+AUD_API ImpulseResponseP* checkImpulseResponse(PyObject* impulseResponse)
+{
+ if(!PyObject_TypeCheck(impulseResponse, &ImpulseResponseType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type ImpulseResponse!");
+ return nullptr;
+ }
+
+ return (ImpulseResponseP*)impulseResponse;
+}
+
+
+bool initializeImpulseResponse()
+{
+ return PyType_Ready(&ImpulseResponseType) >= 0;
+}
+
+
+void addImpulseResponseToModule(PyObject* module)
+{
+ Py_INCREF(&ImpulseResponseType);
+ PyModule_AddObject(module, "ImpulseResponse", (PyObject *)&ImpulseResponseType);
+}
diff --git a/extern/audaspace/bindings/python/PyImpulseResponse.h b/extern/audaspace/bindings/python/PyImpulseResponse.h
new file mode 100644
index 00000000000..3e974c0701c
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyImpulseResponse.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ImpulseResponse;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ImpulseResponse* impulseResponse;
+} ImpulseResponseP;
+
+extern AUD_API PyObject* ImpulseResponse_empty();
+extern AUD_API ImpulseResponseP* checkImpulseResponse(PyObject* impulseResponse);
+
+bool initializeImpulseResponse();
+void addImpulseResponseToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyPlaybackManager.cpp b/extern/audaspace/bindings/python/PyPlaybackManager.cpp
new file mode 100644
index 00000000000..9b6614cae9a
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyPlaybackManager.cpp
@@ -0,0 +1,389 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PyPlaybackManager.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+
+#include "Exception.h"
+#include "fx/PlaybackManager.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+PlaybackManager_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ PlaybackManagerP* self = (PlaybackManagerP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:catKey", &object))
+ return nullptr;
+ Device* device = checkDevice(object);
+
+ try
+ {
+ self->playbackManager = new std::shared_ptr<aud::PlaybackManager>(new aud::PlaybackManager(*reinterpret_cast<std::shared_ptr<aud::IDevice>*>(device->device)));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+PlaybackManager_dealloc(PlaybackManagerP* self)
+{
+ if(self->playbackManager)
+ delete reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_play_doc,
+ "setVolume(sound, catKey)\n\n"
+ "Plays a sound through the playback manager and assigns it to a category.\n\n"
+ ":arg sound: The sound to play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg catKey: the key of the category in which the sound will be added, if it doesn't exist, a new one will be created.\n"
+ ":type catKey: int\n"
+ ":return: The playback handle with which playback can be controlled with.\n"
+ ":rtype: :class:`Handle`");
+
+static PyObject *
+PlaybackManager_play(PlaybackManagerP* self, PyObject* args)
+{
+ PyObject* object;
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "OI:catKey", &object, &cat))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ Handle* handle;
+
+ handle = (Handle*)Handle_empty();
+ if(handle != nullptr)
+ {
+ try
+ {
+ handle->handle = new std::shared_ptr<aud::IHandle>((*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->play(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound), cat));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(handle);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)handle;
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_resume_doc,
+ "resume(catKey)\n\n"
+ "Resumes playback of the catgory.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+PlaybackManager_resume(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->resume(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_pause_doc,
+ "pause(catKey)\n\n"
+ "Pauses playback of the category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+PlaybackManager_pause(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->pause(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_add_category_doc,
+ "addCategory(volume)\n\n"
+ "Adds a category with a custom volume.\n\n"
+ ":arg volume: The volume for ther new category.\n"
+ ":type volume: float\n"
+ ":return: The key of the new category.\n"
+ ":rtype: int\n\n");
+
+static PyObject *
+PlaybackManager_add_category(PlaybackManagerP* self, PyObject* args)
+{
+ float vol;
+
+ if(!PyArg_ParseTuple(args, "f:volume", &vol))
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("I", (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->addCategory(vol));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_get_volume_doc,
+ "getVolume(catKey)\n\n"
+ "Retrieves the volume of a category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: The volume of the cateogry.\n"
+ ":rtype: float\n\n");
+
+static PyObject *
+PlaybackManager_get_volume(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->getVolume(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_set_volume_doc,
+ "setVolume(volume, catKey)\n\n"
+ "Changes the volume of a category.\n\n"
+ ":arg volume: the new volume value.\n"
+ ":type volume: float\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: int\n\n");
+
+static PyObject *
+PlaybackManager_set_volume(PlaybackManagerP* self, PyObject* args)
+{
+ float volume;
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "fI:volume", &volume, &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->setVolume(volume, cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_stop_doc,
+ "stop(catKey)\n\n"
+ "Stops playback of the category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n");
+
+static PyObject *
+PlaybackManager_stop(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->stop(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_clean_doc,
+ "clean()\n\n"
+ "Cleans all the invalid and finished sound from the playback manager.\n\n");
+
+static PyObject *
+PlaybackManager_clean(PlaybackManagerP* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->clean();
+ Py_RETURN_NONE;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef PlaybackManager_methods[] = {
+ { "play", (PyCFunction)PlaybackManager_play, METH_VARARGS | METH_KEYWORDS,
+ M_aud_PlaybackManager_play_doc
+ },
+ { "resume", (PyCFunction)PlaybackManager_resume, METH_VARARGS,
+ M_aud_PlaybackManager_resume_doc
+ },
+ { "pause", (PyCFunction)PlaybackManager_pause, METH_VARARGS,
+ M_aud_PlaybackManager_pause_doc
+ },
+ { "stop", (PyCFunction)PlaybackManager_stop, METH_VARARGS,
+ M_aud_PlaybackManager_stop_doc
+ },
+ { "addCategory", (PyCFunction)PlaybackManager_add_category, METH_VARARGS,
+ M_aud_PlaybackManager_add_category_doc
+ },
+ { "getVolume", (PyCFunction)PlaybackManager_get_volume, METH_VARARGS,
+ M_aud_PlaybackManager_get_volume_doc
+ },
+ { "setVolume", (PyCFunction)PlaybackManager_set_volume, METH_VARARGS,
+ M_aud_PlaybackManager_set_volume_doc
+ },
+ { "clean", (PyCFunction)PlaybackManager_clean, METH_NOARGS,
+ M_aud_PlaybackManager_clean_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_PlaybackManager_doc,
+ "A PlabackManager object allows to easily control groups os sounds organized in categories.");
+
+PyTypeObject PlaybackManagerType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.PlaybackManager", /* tp_name */
+ sizeof(PlaybackManagerP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PlaybackManager_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_PlaybackManager_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ PlaybackManager_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PlaybackManager_new, /* tp_new */
+};
+
+AUD_API PyObject* PlaybackManager_empty()
+{
+ return PlaybackManagerType.tp_alloc(&PlaybackManagerType, 0);
+}
+
+
+AUD_API PlaybackManagerP* checkPlaybackManager(PyObject* playbackManager)
+{
+ if(!PyObject_TypeCheck(playbackManager, &PlaybackManagerType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type PlaybackManager!");
+ return nullptr;
+ }
+
+ return (PlaybackManagerP*)playbackManager;
+}
+
+
+bool initializePlaybackManager()
+{
+ return PyType_Ready(&PlaybackManagerType) >= 0;
+}
+
+
+void addPlaybackManagerToModule(PyObject* module)
+{
+ Py_INCREF(&PlaybackManagerType);
+ PyModule_AddObject(module, "PlaybackManager", (PyObject *)&PlaybackManagerType);
+}
diff --git a/extern/audaspace/bindings/python/PyPlaybackManager.h b/extern/audaspace/bindings/python/PyPlaybackManager.h
new file mode 100644
index 00000000000..f26df1b32d0
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyPlaybackManager.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_PlaybackManager;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_PlaybackManager* playbackManager;
+} PlaybackManagerP;
+
+extern AUD_API PyObject* PlaybackManager_empty();
+extern AUD_API PlaybackManagerP* checkPlaybackManager(PyObject* playbackManager);
+
+bool initializePlaybackManager();
+void addPlaybackManagerToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PySequence.cpp b/extern/audaspace/bindings/python/PySequence.cpp
new file mode 100644
index 00000000000..d4773c743ee
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequence.cpp
@@ -0,0 +1,655 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PySequence.h"
+
+#include "PySound.h"
+#include "PySequenceEntry.h"
+
+#include "sequence/AnimateableProperty.h"
+#include "sequence/Sequence.h"
+#include "Exception.h"
+
+#include <vector>
+#include <structmember.h>
+
+using aud::Channels;
+using aud::DistanceModel;
+using aud::Exception;
+using aud::ISound;
+using aud::AnimateableProperty;
+using aud::AnimateablePropertyType;
+using aud::Specs;
+
+extern PyObject* AUDError;
+
+// ====================================================================
+
+static void
+Sequence_dealloc(Sequence* self)
+{
+ if(self->sequence)
+ delete reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Sequence_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Sequence* self;
+
+ int channels = aud::CHANNELS_STEREO;
+ double rate = aud::RATE_48000;
+ float fps = 30.0f;
+ bool muted = false;
+ PyObject* mutedo = nullptr;
+
+ self = (Sequence*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ static const char* kwlist[] = {"channels", "rate", "fps", "muted", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|idfO:Sequence", const_cast<char**>(kwlist), &channels, &rate, &fps, &mutedo))
+ {
+ Py_DECREF(self);
+ return nullptr;
+ }
+
+ if(mutedo)
+ {
+ if(!PyBool_Check(mutedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return nullptr;
+ }
+
+ muted = mutedo == Py_True;
+ }
+
+ aud::Specs specs;
+ specs.channels = static_cast<aud::Channels>(channels);
+ specs.rate = rate;
+
+ try
+ {
+ self->sequence = new std::shared_ptr<aud::Sequence>(new aud::Sequence(specs, fps, muted));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_add_doc,
+ "add()\n\n"
+ "Adds a new entry to the scene.\n"
+ ":arg sound: The sound this entry should play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg begin: The start time.\n"
+ ":type begin: float\n"
+ ":arg end: The end time or a negative value if determined by the sound.\n"
+ ":type end: float\n"
+ ":arg skip: How much seconds should be skipped at the beginning.\n"
+ ":type skip: float\n"
+ ":return: The entry added.\n"
+ ":rtype: :class:`SequenceEntry`");
+
+static PyObject *
+Sequence_add(Sequence* self, PyObject* args, PyObject* kwds)
+{
+ PyObject* object;
+ float begin;
+ float end = -1.0f;
+ float skip = 0.0f;
+
+ static const char* kwlist[] = {"sound", "begin", "end", "skip", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "Of|ff:add", const_cast<char**>(kwlist), &object, &begin, &end, &skip))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ SequenceEntry* entry;
+
+ entry = (SequenceEntry*)SequenceEntry_empty();
+ if(entry != nullptr)
+ {
+ try
+ {
+ entry->entry = new std::shared_ptr<aud::SequenceEntry>((*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->add(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound), begin, end, skip));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(entry);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)entry;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_remove_doc,
+ "reomve()\n\n"
+ "Adds a new entry to the scene.\n"
+ ":arg entry: The entry to remove.\n"
+ ":type entry: :class:`SequenceEntry`\n");
+
+static PyObject *
+Sequence_remove(Sequence* self, PyObject* args)
+{
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "O:remove", &object))
+ return nullptr;
+
+ SequenceEntry* entry = checkSequenceEntry(object);
+
+ if(!entry)
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->remove(*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(entry->entry));
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(entry);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_setAnimationData_doc,
+ "setAnimationData()\n\n"
+ "Writes animation data to a sequence.\n\n"
+ ":arg type: The type of animation data.\n"
+ ":type type: int\n"
+ ":arg frame: The frame this data is for.\n"
+ ":type frame: int\n"
+ ":arg data: The data to write.\n"
+ ":type data: sequence of float\n"
+ ":arg animated: Whether the attribute is animated.\n"
+ ":type animated: bool");
+
+static PyObject *
+Sequence_setAnimationData(Sequence* self, PyObject* args)
+{
+ int type, frame;
+ PyObject* py_data;
+ Py_ssize_t py_data_len;
+ PyObject* animatedo;
+ bool animated;
+
+ if(!PyArg_ParseTuple(args, "iiOO:setAnimationData", &type, &frame, &py_data, &animatedo))
+ return nullptr;
+
+ if(!PySequence_Check(py_data))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_data_len= PySequence_Size(py_data);
+
+ std::vector<float> data;
+ data.resize(py_data_len);
+
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_data_len; i++)
+ {
+ py_value = PySequence_GetItem(py_data, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ data.push_back(value);
+ }
+
+ if(!PyBool_Check(animatedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "animated is not a boolean!");
+ return nullptr;
+ }
+
+ animated = animatedo == Py_True;
+
+ try
+ {
+ AnimateableProperty* prop = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+
+ if(prop->getCount() != py_data_len)
+ {
+ PyErr_SetString(PyExc_ValueError, "the amount of floats doesn't fit the animated property");
+ return nullptr;
+ }
+
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(&data[0], frame, 1);
+ }
+ else
+ {
+ prop->write(&data[0]);
+ }
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Sequence_methods[] = {
+ {"add", (PyCFunction)Sequence_add, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Sequence_add_doc
+ },
+ {"remove", (PyCFunction)Sequence_remove, METH_VARARGS,
+ M_aud_Sequence_remove_doc
+ },
+ {"setAnimationData", (PyCFunction)Sequence_setAnimationData, METH_VARARGS,
+ M_aud_Sequence_setAnimationData_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sequence_channels_doc,
+ "The channel count of the sequence.");
+
+static PyObject *
+Sequence_get_channels(Sequence* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpecs();
+ return Py_BuildValue("i", specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_channels(Sequence* self, PyObject* args, void* nothing)
+{
+ int channels;
+
+ if(!PyArg_Parse(args, "i:channels", &channels))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence> sequence = *reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Specs specs = sequence->getSpecs();
+ specs.channels = static_cast<Channels>(channels);
+ sequence->setSpecs(specs);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_distance_model_doc,
+ "The distance model of the sequence.\n\n"
+ ".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
+
+static PyObject *
+Sequence_get_distance_model(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getDistanceModel());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_distance_model(Sequence* self, PyObject* args, void* nothing)
+{
+ int distance_model;
+
+ if(!PyArg_Parse(args, "i:distance_model", &distance_model))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setDistanceModel(static_cast<DistanceModel>(distance_model));
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_doppler_factor_doc,
+ "The doppler factor of the sequence.\n"
+ "This factor is a scaling factor for the velocity vectors in "
+ "doppler calculation. So a value bigger than 1 will exaggerate "
+ "the effect as it raises the velocity.");
+
+static PyObject *
+Sequence_get_doppler_factor(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getDopplerFactor());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_doppler_factor(Sequence* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:doppler_factor", &factor))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setDopplerFactor(factor);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_fps_doc,
+ "The listeners's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Sequence_get_fps(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getFPS());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_fps(Sequence* self, PyObject* args, void* nothing)
+{
+ float fps;
+
+ if(!PyArg_Parse(args, "f:fps", &fps))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setFPS(fps);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_muted_doc,
+ "Whether the whole sequence is muted.\n");
+
+static PyObject *
+Sequence_get_muted(Sequence* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::Sequence>* sequence = reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ return PyBool_FromLong((long)(*sequence)->isMuted());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_muted(Sequence* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return -1;
+ }
+
+ bool muted = args == Py_True;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence>* sequence = reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ (*sequence)->mute(muted);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_rate_doc,
+ "The sampling rate of the sequence in Hz.");
+
+static PyObject *
+Sequence_get_rate(Sequence* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpecs();
+ return Py_BuildValue("d", specs.rate);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_rate(Sequence* self, PyObject* args, void* nothing)
+{
+ double rate;
+
+ if(!PyArg_Parse(args, "d:rate", &rate))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence> sequence = *reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Specs specs = sequence->getSpecs();
+ specs.rate = rate;
+ sequence->setSpecs(specs);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_speed_of_sound_doc,
+ "The speed of sound of the sequence.\n"
+ "The speed of sound in air is typically 343.3 m/s.");
+
+static PyObject *
+Sequence_get_speed_of_sound(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpeedOfSound());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_speed_of_sound(Sequence* self, PyObject* args, void* nothing)
+{
+ float speed;
+
+ if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setSpeedOfSound(speed);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+static PyGetSetDef Sequence_properties[] = {
+ {(char*)"channels", (getter)Sequence_get_channels, (setter)Sequence_set_channels,
+ M_aud_Sequence_channels_doc, nullptr },
+ {(char*)"distance_model", (getter)Sequence_get_distance_model, (setter)Sequence_set_distance_model,
+ M_aud_Sequence_distance_model_doc, nullptr },
+ {(char*)"doppler_factor", (getter)Sequence_get_doppler_factor, (setter)Sequence_set_doppler_factor,
+ M_aud_Sequence_doppler_factor_doc, nullptr },
+ {(char*)"fps", (getter)Sequence_get_fps, (setter)Sequence_set_fps,
+ M_aud_Sequence_fps_doc, nullptr },
+ {(char*)"muted", (getter)Sequence_get_muted, (setter)Sequence_set_muted,
+ M_aud_Sequence_muted_doc, nullptr },
+ {(char*)"rate", (getter)Sequence_get_rate, (setter)Sequence_set_rate,
+ M_aud_Sequence_rate_doc, nullptr },
+ {(char*)"speed_of_sound", (getter)Sequence_get_speed_of_sound, (setter)Sequence_set_speed_of_sound,
+ M_aud_Sequence_speed_of_sound_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sequence_doc,
+ "This sound represents sequenced entries to play a sound scene.");
+
+extern PyTypeObject SoundType;
+
+static PyTypeObject SequenceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Sequence", /* tp_name */
+ sizeof(Sequence), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Sequence_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Sequence_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Sequence_methods, /* tp_methods */
+ 0, /* tp_members */
+ Sequence_properties, /* tp_getset */
+ &SoundType, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Sequence_new, /* tp_new */
+};
+
+AUD_API PyObject* Sequence_empty()
+{
+ return SequenceType.tp_alloc(&SequenceType, 0);
+}
+
+
+AUD_API Sequence* checkSequence(PyObject* sequence)
+{
+ if(!PyObject_TypeCheck(sequence, &SequenceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sequence!");
+ return nullptr;
+ }
+
+ return (Sequence*)sequence;
+}
+
+
+bool initializeSequence()
+{
+ return PyType_Ready(&SequenceType) >= 0;
+}
+
+
+void addSequenceToModule(PyObject* module)
+{
+ Py_INCREF(&SequenceType);
+ PyModule_AddObject(module, "Sequence", (PyObject *)&SequenceType);
+}
diff --git a/extern/audaspace/bindings/python/PySequence.h b/extern/audaspace/bindings/python/PySequence.h
new file mode 100644
index 00000000000..17855121dda
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequence.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_Sequence;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_Sequence* sequence;
+} Sequence;
+
+extern AUD_API PyObject* Sequence_empty();
+extern AUD_API Sequence* checkSequence(PyObject* sequence);
+
+bool initializeSequence();
+void addSequenceToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySequenceEntry.cpp b/extern/audaspace/bindings/python/PySequenceEntry.cpp
new file mode 100644
index 00000000000..e6a034ed880
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequenceEntry.cpp
@@ -0,0 +1,740 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PySequenceEntry.h"
+
+#include "PySound.h"
+
+#include "Exception.h"
+#include "sequence/AnimateableProperty.h"
+#include "sequence/SequenceEntry.h"
+
+#include <structmember.h>
+#include <vector>
+
+using aud::Exception;
+using aud::AnimateableProperty;
+using aud::AnimateablePropertyType;
+using aud::ISound;
+
+extern PyObject* AUDError;
+
+// ====================================================================
+
+static void
+SequenceEntry_dealloc(SequenceEntry* self)
+{
+ if(self->entry)
+ delete reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_move_doc,
+ "move()\n\n"
+ "Moves the entry.\n\n"
+ ":arg begin: The new start time.\n"
+ ":type begin: float\n"
+ ":arg end: The new end time or a negative value if unknown.\n"
+ ":type end: float\n"
+ ":arg skip: How many seconds to skip at the beginning.\n"
+ ":type skip: float\n");
+
+static PyObject *
+SequenceEntry_move(SequenceEntry* self, PyObject* args)
+{
+ float begin, end, skip;
+
+ if(!PyArg_ParseTuple(args, "fff:move", &begin, &end, &skip))
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->move(begin, end, skip);
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_setAnimationData_doc,
+ "setAnimationData()\n\n"
+ "Writes animation data to a sequenced entry.\n\n"
+ ":arg type: The type of animation data.\n"
+ ":type type: int\n"
+ ":arg frame: The frame this data is for.\n"
+ ":type frame: int\n"
+ ":arg data: The data to write.\n"
+ ":type data: sequence of float\n"
+ ":arg animated: Whether the attribute is animated.\n"
+ ":type animated: bool");
+
+static PyObject *
+SequenceEntry_setAnimationData(SequenceEntry* self, PyObject* args)
+{
+ int type, frame;
+ PyObject* py_data;
+ Py_ssize_t py_data_len;
+ PyObject* animatedo;
+ bool animated;
+
+ if(!PyArg_ParseTuple(args, "iiOO:setAnimationData", &type, &frame, &py_data, &animatedo))
+ return nullptr;
+
+ if(!PySequence_Check(py_data))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_data_len= PySequence_Size(py_data);
+
+ std::vector<float> data;
+ data.resize(py_data_len);
+
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_data_len; i++)
+ {
+ py_value = PySequence_GetItem(py_data, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ data.push_back(value);
+ }
+
+ if(!PyBool_Check(animatedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "animated is not a boolean!");
+ return nullptr;
+ }
+
+ animated = animatedo == Py_True;
+
+ try
+ {
+ AnimateableProperty* prop = (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+
+ if(prop->getCount() != py_data_len)
+ {
+ PyErr_SetString(PyExc_ValueError, "the amount of floats doesn't fit the animated property");
+ return nullptr;
+ }
+
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(&data[0], frame, 1);
+ }
+ else
+ {
+ prop->write(&data[0]);
+ }
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef SequenceEntry_methods[] = {
+ {"move", (PyCFunction)SequenceEntry_move, METH_VARARGS,
+ M_aud_SequenceEntry_move_doc
+ },
+ {"setAnimationData", (PyCFunction)SequenceEntry_setAnimationData, METH_VARARGS,
+ M_aud_SequenceEntry_setAnimationData_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_SequenceEntry_attenuation_doc,
+ "This factor is used for distance based attenuation of the "
+ "source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_attenuation(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getAttenuation());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_attenuation(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:attenuation", &factor))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setAttenuation(factor);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_inner_doc,
+ "The opening angle of the inner cone of the source. If the cone "
+ "values of a source are set there are two (audible) cones with "
+ "the apex at the :attr:`location` of the source and with infinite "
+ "height, heading in the direction of the source's "
+ ":attr:`orientation`.\n"
+ "In the inner cone the volume is normal. Outside the outer cone "
+ "the volume will be :attr:`cone_volume_outer` and in the area "
+ "between the volume will be interpolated linearly.");
+
+static PyObject *
+SequenceEntry_get_cone_angle_inner(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeAngleInner());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_angle_inner(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeAngleInner(angle);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_outer_doc,
+ "The opening angle of the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+SequenceEntry_get_cone_angle_outer(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeAngleOuter());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_angle_outer(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeAngleOuter(angle);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_volume_outer_doc,
+ "The volume outside the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+SequenceEntry_get_cone_volume_outer(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeVolumeOuter());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_volume_outer(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeVolumeOuter(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_distance_maximum_doc,
+ "The maximum distance of the source.\n"
+ "If the listener is further away the source volume will be 0.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_distance_maximum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getDistanceMaximum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_distance_maximum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_maximum", &distance))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setDistanceMaximum(distance);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_distance_reference_doc,
+ "The reference distance of the source.\n"
+ "At this distance the volume will be exactly :attr:`volume`.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_distance_reference(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getDistanceReference());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_distance_reference(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_reference", &distance))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setDistanceReference(distance);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_muted_doc,
+ "Whether the entry is muted.\n");
+
+static PyObject *
+SequenceEntry_get_muted(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return PyBool_FromLong((long)(*entry)->isMuted());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_muted(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return -1;
+ }
+
+ bool muted = args == Py_True;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->mute(muted);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_relative_doc,
+ "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
+
+static PyObject *
+SequenceEntry_get_relative(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return PyBool_FromLong((long)(*entry)->isRelative());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+SequenceEntry_set_relative(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+ return -1;
+ }
+
+ bool relative = (args == Py_True);
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setRelative(relative);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_sound_doc,
+ "The sound the entry is representing and will be played in the sequence.");
+
+static PyObject *
+SequenceEntry_get_sound(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ Sound* object = (Sound*) Sound_empty();
+ if(object)
+ {
+ object->sound = new std::shared_ptr<ISound>((*entry)->getSound());
+ return (PyObject *) object;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+SequenceEntry_set_sound(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ Sound* sound = checkSound(args);
+
+ if(!sound)
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setSound(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound));
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_volume_maximum_doc,
+ "The maximum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_volume_maximum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getVolumeMaximum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_volume_maximum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_maximum", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setVolumeMaximum(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_volume_minimum_doc,
+ "The minimum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_volume_minimum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getVolumeMinimum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_volume_minimum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_minimum", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setVolumeMinimum(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyGetSetDef SequenceEntry_properties[] = {
+ {(char*)"attenuation", (getter)SequenceEntry_get_attenuation, (setter)SequenceEntry_set_attenuation,
+ M_aud_SequenceEntry_attenuation_doc, nullptr },
+ {(char*)"cone_angle_inner", (getter)SequenceEntry_get_cone_angle_inner, (setter)SequenceEntry_set_cone_angle_inner,
+ M_aud_SequenceEntry_cone_angle_inner_doc, nullptr },
+ {(char*)"cone_angle_outer", (getter)SequenceEntry_get_cone_angle_outer, (setter)SequenceEntry_set_cone_angle_outer,
+ M_aud_SequenceEntry_cone_angle_outer_doc, nullptr },
+ {(char*)"cone_volume_outer", (getter)SequenceEntry_get_cone_volume_outer, (setter)SequenceEntry_set_cone_volume_outer,
+ M_aud_SequenceEntry_cone_volume_outer_doc, nullptr },
+ {(char*)"distance_maximum", (getter)SequenceEntry_get_distance_maximum, (setter)SequenceEntry_set_distance_maximum,
+ M_aud_SequenceEntry_distance_maximum_doc, nullptr },
+ {(char*)"distance_reference", (getter)SequenceEntry_get_distance_reference, (setter)SequenceEntry_set_distance_reference,
+ M_aud_SequenceEntry_distance_reference_doc, nullptr },
+ {(char*)"muted", (getter)SequenceEntry_get_muted, (setter)SequenceEntry_set_muted,
+ M_aud_SequenceEntry_muted_doc, nullptr },
+ {(char*)"relative", (getter)SequenceEntry_get_relative, (setter)SequenceEntry_set_relative,
+ M_aud_SequenceEntry_relative_doc, nullptr },
+ {(char*)"sound", (getter)SequenceEntry_get_sound, (setter)SequenceEntry_set_sound,
+ M_aud_SequenceEntry_sound_doc, nullptr },
+ {(char*)"volume_maximum", (getter)SequenceEntry_get_volume_maximum, (setter)SequenceEntry_set_volume_maximum,
+ M_aud_SequenceEntry_volume_maximum_doc, nullptr },
+ {(char*)"volume_minimum", (getter)SequenceEntry_get_volume_minimum, (setter)SequenceEntry_set_volume_minimum,
+ M_aud_SequenceEntry_volume_minimum_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_SequenceEntry_doc,
+ "SequenceEntry objects represent an entry of a sequenced sound.");
+
+static PyTypeObject SequenceEntryType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.SequenceEntry", /* tp_name */
+ sizeof(SequenceEntry), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SequenceEntry_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_SequenceEntry_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ SequenceEntry_methods, /* tp_methods */
+ 0, /* tp_members */
+ SequenceEntry_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+AUD_API PyObject* SequenceEntry_empty()
+{
+ return SequenceEntryType.tp_alloc(&SequenceEntryType, 0);
+}
+
+
+AUD_API SequenceEntry* checkSequenceEntry(PyObject* entry)
+{
+ if(!PyObject_TypeCheck(entry, &SequenceEntryType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type SequenceEntry!");
+ return nullptr;
+ }
+
+ return (SequenceEntry*)entry;
+}
+
+
+bool initializeSequenceEntry()
+{
+ return PyType_Ready(&SequenceEntryType) >= 0;
+}
+
+
+void addSequenceEntryToModule(PyObject* module)
+{
+ Py_INCREF(&SequenceEntryType);
+ PyModule_AddObject(module, "SequenceEntry", (PyObject *)&SequenceEntryType);
+}
diff --git a/extern/audaspace/bindings/python/PySequenceEntry.h b/extern/audaspace/bindings/python/PySequenceEntry.h
new file mode 100644
index 00000000000..7bb4ae4a281
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequenceEntry.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_SequenceEntry;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_SequenceEntry* entry;
+} SequenceEntry;
+
+extern AUD_API PyObject* SequenceEntry_empty();
+extern AUD_API SequenceEntry* checkSequenceEntry(PyObject* entry);
+
+bool initializeSequenceEntry();
+void addSequenceEntryToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySound.cpp b/extern/audaspace/bindings/python/PySound.cpp
new file mode 100644
index 00000000000..2ab1974be49
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySound.cpp
@@ -0,0 +1,1966 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "PySound.h"
+#include "PySource.h"
+#include "PyThreadPool.h"
+
+#ifdef WITH_CONVOLUTION
+#include "PyHRTF.h"
+#include "PyImpulseResponse.h"
+#endif
+
+#include "Exception.h"
+#include "file/File.h"
+#include "file/FileWriter.h"
+#include "util/StreamBuffer.h"
+#include "generator/Sawtooth.h"
+#include "generator/Silence.h"
+#include "generator/Sine.h"
+#include "generator/Square.h"
+#include "generator/Triangle.h"
+#include "fx/Accumulator.h"
+#include "fx/ADSR.h"
+#include "fx/Delay.h"
+#include "fx/Envelope.h"
+#include "fx/Fader.h"
+#include "fx/Highpass.h"
+#include "fx/IIRFilter.h"
+#include "fx/Limiter.h"
+#include "fx/Loop.h"
+#include "fx/Lowpass.h"
+#include "fx/MutableSound.h"
+#include "fx/Pitch.h"
+#include "fx/Reverse.h"
+#include "fx/SoundList.h"
+#include "fx/Sum.h"
+#include "fx/Threshold.h"
+#include "fx/Volume.h"
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+#include "respec/LinearResample.h"
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+#include "sequence/Double.h"
+#include "sequence/PingPong.h"
+#include "sequence/Superpose.h"
+
+#ifdef WITH_CONVOLUTION
+#include "fx/BinauralSound.h"
+#include "fx/ConvolverSound.h"
+#endif
+
+#include <cstring>
+#include <structmember.h>
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/ndarrayobject.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+
+static void
+Sound_dealloc(Sound* self)
+{
+ if(self->sound)
+ delete reinterpret_cast<std::shared_ptr<ISound>*>(self->sound);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ static const char* kwlist[] = {"filename", nullptr};
+ const char* filename = nullptr;
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Sound", const_cast<char**>(kwlist), &filename))
+ {
+ Py_DECREF(self);
+ return nullptr;
+ }
+
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new File(filename));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_data_doc,
+ "data()\n\n"
+ "Retrieves the data of the sound as numpy array.\n\n"
+ ":return: A two dimensional numpy float array.\n"
+ ":rtype: :class:`numpy.ndarray`\n\n"
+ ".. note:: Best efficiency with cached sounds.");
+
+static PyObject *
+Sound_data(Sound* self)
+{
+ std::shared_ptr<ISound> sound = *reinterpret_cast<std::shared_ptr<ISound>*>(self->sound);
+
+ auto stream_buffer = std::dynamic_pointer_cast<StreamBuffer>(sound);
+ if(!stream_buffer)
+ stream_buffer = std::make_shared<StreamBuffer>(sound);
+ Specs specs = stream_buffer->getSpecs();
+ auto buffer = stream_buffer->getBuffer();
+
+ npy_intp dimensions[2];
+ dimensions[0] = buffer->getSize() / AUD_SAMPLE_SIZE(specs);
+ dimensions[1] = specs.channels;
+
+ PyArrayObject* array = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNew(2, dimensions, NPY_FLOAT));
+
+ sample_t* data = reinterpret_cast<sample_t*>(PyArray_DATA(array));
+
+ std::memcpy(data, buffer->getBuffer(), buffer->getSize());
+
+ Py_INCREF(array);
+
+ return reinterpret_cast<PyObject*>(array);
+}
+
+PyDoc_STRVAR(M_aud_Sound_write_doc,
+ "write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
+ "Writes the sound to a file.\n\n"
+ ":arg filename: The path to write to.\n"
+ ":type filename: string\n"
+ ":arg rate: The sample rate to write with.\n"
+ ":type rate: int\n"
+ ":arg channels: The number of channels to write with.\n"
+ ":type channels: int\n"
+ ":arg format: The sample format to write with.\n"
+ ":type format: int\n"
+ ":arg container: The container format for the file.\n"
+ ":type container: int\n"
+ ":arg codec: The codec to use in the file.\n"
+ ":type codec: int\n"
+ ":arg bitrate: The bitrate to write with.\n"
+ ":type bitrate: int\n"
+ ":arg buffersize: The size of the writing buffer.\n"
+ ":type buffersize: int\n");
+
+static PyObject *
+Sound_write(Sound* self, PyObject* args, PyObject* kwds)
+{
+ const char* filename = nullptr;
+ int rate = RATE_INVALID;
+ Channels channels = CHANNELS_INVALID;
+ SampleFormat format = FORMAT_INVALID;
+ Container container = CONTAINER_INVALID;
+ Codec codec = CODEC_INVALID;
+ int bitrate = 0;
+ int buffersize = 0;
+
+ static const char* kwlist[] = {"filename", "rate", "channels", "format", "container", "codec", "bitrate", "buffersize", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|iiiiiii:write", const_cast<char**>(kwlist), &filename, &rate, &channels, &format, &container, &codec, &bitrate, &buffersize))
+ return nullptr;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader();
+
+ DeviceSpecs specs;
+ specs.specs = reader->getSpecs();
+
+ if((rate != RATE_INVALID) && (specs.rate != rate))
+ {
+ specs.rate = rate;
+ reader = std::make_shared<JOSResampleReader>(reader, rate);
+ }
+
+ if((channels != CHANNELS_INVALID) && (specs.channels != channels))
+ {
+ specs.channels = channels;
+ reader = std::make_shared<ChannelMapperReader>(reader, channels);
+ }
+
+ if(format == FORMAT_INVALID)
+ format = FORMAT_S16;
+ specs.format = format;
+
+ const char* invalid_container_error = "Container could not be determined from filename.";
+
+ if(container == CONTAINER_INVALID)
+ {
+ std::string path = filename;
+
+ if(path.length() < 4)
+ {
+ PyErr_SetString(AUDError, invalid_container_error);
+ return nullptr;
+ }
+
+ std::string extension = path.substr(path.length() - 4);
+
+ if(extension == ".ac3")
+ container = CONTAINER_AC3;
+ else if(extension == "flac")
+ container = CONTAINER_FLAC;
+ else if(extension == ".mkv")
+ container = CONTAINER_MATROSKA;
+ else if(extension == ".mp2")
+ container = CONTAINER_MP2;
+ else if(extension == ".mp3")
+ container = CONTAINER_MP3;
+ else if(extension == ".ogg")
+ container = CONTAINER_OGG;
+ else if(extension == ".wav")
+ container = CONTAINER_WAV;
+ else
+ {
+ PyErr_SetString(AUDError, invalid_container_error);
+ return nullptr;
+ }
+ }
+
+ if(codec == CODEC_INVALID)
+ {
+ switch(container)
+ {
+ case CONTAINER_AC3:
+ codec = CODEC_AC3;
+ break;
+ case CONTAINER_FLAC:
+ codec = CODEC_FLAC;
+ break;
+ case CONTAINER_MATROSKA:
+ codec = CODEC_OPUS;
+ break;
+ case CONTAINER_MP2:
+ codec = CODEC_MP2;
+ break;
+ case CONTAINER_MP3:
+ codec = CODEC_MP3;
+ break;
+ case CONTAINER_OGG:
+ codec = CODEC_VORBIS;
+ break;
+ case CONTAINER_WAV:
+ codec = CODEC_PCM;
+ break;
+ default:
+ PyErr_SetString(AUDError, "Unknown container, cannot select default codec.");
+ return nullptr;
+ }
+ }
+
+ if(buffersize <= 0)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, specs, container, codec, bitrate);
+ FileWriter::writeReader(reader, writer, 0, buffersize);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(M_aud_Sound_buffer_doc,
+ "buffer(data, rate)\n\n"
+ "Creates a sound from a data buffer.\n\n"
+ ":arg data: The data as two dimensional numpy array.\n"
+ ":type data: numpy.ndarray\n"
+ ":arg rate: The sample rate.\n"
+ ":type rate: double\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_buffer(PyTypeObject* type, PyObject* args)
+{
+ PyArrayObject* array = nullptr;
+ double rate = RATE_INVALID;
+
+ if(!PyArg_ParseTuple(args, "Od:buffer", &array, &rate))
+ return nullptr;
+
+ if((!PyObject_TypeCheck(reinterpret_cast<PyObject*>(array), &PyArray_Type)) || (PyArray_TYPE(array) != NPY_FLOAT))
+ {
+ PyErr_SetString(PyExc_TypeError, "The data needs to be supplied as float32 numpy array!");
+ return nullptr;
+ }
+
+ if(PyArray_NDIM(array) > 2)
+ {
+ PyErr_SetString(PyExc_TypeError, "The array needs to have one or two dimensions!");
+ return nullptr;
+ }
+
+ if(rate <= 0)
+ {
+ PyErr_SetString(PyExc_TypeError, "The sample rate has to be positive!");
+ return nullptr;
+ }
+
+ Specs specs;
+ specs.rate = rate;
+ specs.channels = CHANNELS_MONO;
+
+ if(PyArray_NDIM(array) == 2)
+ specs.channels = static_cast<Channels>(PyArray_DIM(array, 1));
+
+ int size = PyArray_DIM(array, 0) * AUD_SAMPLE_SIZE(specs);
+
+ std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(size);
+
+ std::memcpy(buffer->getBuffer(), PyArray_DATA(array), size);
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<StreamBuffer>(new StreamBuffer(buffer, specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_cache_doc,
+ "cache()\n\n"
+ "Caches a sound into RAM.\n"
+ "This saves CPU usage needed for decoding and file access if the "
+ "underlying sound reads from a file on the harddisk, but it "
+ "consumes a lot of memory.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: Only known-length factories can be buffered.\n\n"
+ ".. warning:: Raw PCM data needs a lot of space, only buffer "
+ "short factories.");
+
+static PyObject *
+Sound_cache(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new StreamBuffer(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_file_doc,
+ "file(filename)\n\n"
+ "Creates a sound object of a sound file.\n\n"
+ ":arg filename: Path of the file.\n"
+ ":type filename: string\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\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 sound.");
+
+static PyObject *
+Sound_file(PyTypeObject* type, PyObject* args)
+{
+ const char* filename = nullptr;
+
+ if(!PyArg_ParseTuple(args, "s:file", &filename))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new File(filename));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sawtooth_doc,
+ "sawtooth(frequency, rate=48000)\n\n"
+ "Creates a sawtooth sound which plays a sawtooth wave.\n\n"
+ ":arg frequency: The frequency of the sawtooth 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sawtooth(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:sawtooth", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Sawtooth(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_silence_doc,
+ "silence()\n\n"
+ "Creates a silence sound which plays simple silence.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_silence(PyTypeObject* type)
+{
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Silence());
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sine_doc,
+ "sine(frequency, rate=48000)\n\n"
+ "Creates a sine sound 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sine(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Sine(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_square_doc,
+ "square(frequency, rate=48000)\n\n"
+ "Creates a square sound which plays a square wave.\n\n"
+ ":arg frequency: The frequency of the square 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_square(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:square", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Square(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_triangle_doc,
+ "triangle(frequency, rate=48000)\n\n"
+ "Creates a triangle sound which plays a triangle wave.\n\n"
+ ":arg frequency: The frequency of the triangle 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_triangle(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:triangle", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Triangle(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_accumulate_doc,
+ "accumulate(additive=False)\n\n"
+ "Accumulates a sound by summing over positive input differences thus generating a monotonic sigal. "
+ "If additivity is set to true negative input differences get added too, but positive ones with a factor of two. "
+ "Note that with additivity the signal is not monotonic anymore.\n\n"
+ ":arg additive: Whether the accumulation should be additive or not.\n"
+ ":type time: bool\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_accumulate(Sound* self, PyObject* args)
+{
+ bool additive = false;
+ PyObject* additiveo;
+
+ if(!PyArg_ParseTuple(args, "|O:accumulate", &additiveo))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ if(additiveo != nullptr)
+ {
+ if(!PyBool_Check(additiveo))
+ {
+ PyErr_SetString(PyExc_TypeError, "additive is not a boolean!");
+ return nullptr;
+ }
+
+ additive = additiveo == Py_True;
+ }
+
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Accumulator(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), additive));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_ADSR_doc,
+ "ADSR(attack,decay,sustain,release)\n\n"
+ "Attack-Decay-Sustain-Release envelopes the volume of a sound. "
+ "Note: there is currently no way to trigger the release with this API.\n\n"
+ ":arg attack: The attack time in seconds.\n"
+ ":type attack: float\n"
+ ":arg decay: The decay time in seconds.\n"
+ ":type decay: float\n"
+ ":arg sustain: The sustain level.\n"
+ ":type sustain: float\n"
+ ":arg release: The release level.\n"
+ ":type release: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_ADSR(Sound* self, PyObject* args)
+{
+ float attack, decay, sustain, release;
+
+ if(!PyArg_ParseTuple(args, "ffff:ADSR", &attack, &decay, &sustain, &release))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new ADSR(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), attack, decay, sustain, release));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_delay_doc,
+ "delay(time)\n\n"
+ "Delays by playing adding silence in front of the other sound's "
+ "data.\n\n"
+ ":arg time: How many seconds of silence should be added before "
+ "the sound.\n"
+ ":type time: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_delay(Sound* self, PyObject* args)
+{
+ float delay;
+
+ if(!PyArg_ParseTuple(args, "f:delay", &delay))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Delay(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), delay));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_envelope_doc,
+ "envelope(attack, release, threshold, arthreshold)\n\n"
+ "Delays by playing adding silence in front of the other sound's "
+ "data.\n\n"
+ ":arg attack: The attack factor.\n"
+ ":type attack: float\n"
+ ":arg release: The release factor.\n"
+ ":type release: float\n"
+ ":arg threshold: The general threshold value.\n"
+ ":type threshold: float\n"
+ ":arg arthreshold: The attack/release threshold value.\n"
+ ":type arthreshold: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_envelope(Sound* self, PyObject* args)
+{
+ float attack, release, threshold, arthreshold;
+
+ if(!PyArg_ParseTuple(args, "ffff:envelope", &attack, &release, &threshold, &arthreshold))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Envelope(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), attack, release, threshold, arthreshold));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_fadein_doc,
+ "fadein(start, length)\n\n"
+ "Fades a sound 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: Before the fade starts it plays silence.");
+
+static PyObject *
+Sound_fadein(Sound* self, PyObject* args)
+{
+ float start, length;
+
+ if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Fader(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), FADE_IN, start, length));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
+ "fadeout(start, length)\n\n"
+ "Fades a sound 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: After the fade this sound plays silence, so that "
+ "the length of the sound is not altered.");
+
+static PyObject *
+Sound_fadeout(Sound* self, PyObject* args)
+{
+ float start, length;
+
+ if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Fader(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), FADE_OUT, start, length));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_filter_doc,
+ "filter(b, a = (1))\n\n"
+ "Filters a sound with the supplied IIR filter coefficients.\n"
+ "Without the second parameter you'll get a FIR filter.\n"
+ "If the first value of the a sequence is 0 it will be set to 1 "
+ "automatically.\n"
+ "If the first value of the a sequence is neither 0 nor 1, all "
+ "filter coefficients will be scaled by this value so that it is 1 "
+ "in the end, you don't have to scale yourself.\n\n"
+ ":arg b: The nominator filter coefficients.\n"
+ ":type b: sequence of float\n"
+ ":arg a: The denominator filter coefficients.\n"
+ ":type a: sequence of float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_filter(Sound* self, PyObject* args)
+{
+ PyObject* py_b;
+ PyObject* py_a = nullptr;
+ Py_ssize_t py_a_len;
+ Py_ssize_t py_b_len;
+
+ if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
+ return nullptr;
+
+ if(!PySequence_Check(py_b) || (py_a != nullptr && !PySequence_Check(py_a)))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_a_len= py_a ? PySequence_Size(py_a) : 0;
+ py_b_len= PySequence_Size(py_b);
+
+ if(!py_b_len || ((py_a != nullptr) && !py_a_len))
+ {
+ PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
+ return nullptr;
+ }
+
+ std::vector<float> a, b;
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_b_len; i++)
+ {
+ py_value = PySequence_GetItem(py_b, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ b.push_back(value);
+ }
+
+ if(py_a)
+ {
+ for(Py_ssize_t i = 0; i < py_a_len; i++)
+ {
+ py_value = PySequence_GetItem(py_a, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ a.push_back(value);
+ }
+
+ if(a[0] == 0)
+ a[0] = 1;
+ }
+ else
+ a.push_back(1);
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new IIRFilter(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), b, a));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_highpass(Sound* self, PyObject* args)
+{
+ float frequency;
+ float Q = 0.5;
+
+ if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Highpass(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), frequency, Q));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_limit_doc,
+ "limit(start, end)\n\n"
+ "Limits a sound 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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_limit(Sound* self, PyObject* args)
+{
+ float start, end;
+
+ if(!PyArg_ParseTuple(args, "ff:limit", &start, &end))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Limiter(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), start, end));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_loop_doc,
+ "loop(count)\n\n"
+ "Loops a sound.\n\n"
+ ":arg count: How often the sound should be looped. "
+ "Negative values mean endlessly.\n"
+ ":type count: integer\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: This is a filter function, you might consider using "
+ ":attr:`Handle.loop_count` instead.");
+
+static PyObject *
+Sound_loop(Sound* self, PyObject* args)
+{
+ int loop;
+
+ if(!PyArg_ParseTuple(args, "i:loop", &loop))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Loop(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), loop));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_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:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_lowpass(Sound* self, PyObject* args)
+{
+ float frequency;
+ float Q = 0.5;
+
+ if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Lowpass(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), frequency, Q));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_pitch_doc,
+ "pitch(factor)\n\n"
+ "Changes the pitch of a sound with a specific factor.\n\n"
+ ":arg factor: The factor to change the pitch with.\n"
+ ":type factor: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: This is done by changing the sample rate of the "
+ "underlying sound, 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 *
+Sound_pitch(Sound* self, PyObject* args)
+{
+ float factor;
+
+ if(!PyArg_ParseTuple(args, "f:pitch", &factor))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Pitch(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), factor));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_rechannel_doc,
+ "rechannel(channels)\n\n"
+ "Rechannels the sound.\n\n"
+ ":arg channels: The new channel configuration.\n"
+ ":type channels: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_rechannel(Sound* self, PyObject* args)
+{
+ int channels;
+
+ if(!PyArg_ParseTuple(args, "i:rechannel", &channels))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = static_cast<Channels>(channels);
+ specs.rate = RATE_INVALID;
+ specs.format = FORMAT_INVALID;
+ parent->sound = new std::shared_ptr<ISound>(new ChannelMapper(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_resample_doc,
+ "resample(rate, high_quality)\n\n"
+ "Resamples the sound.\n\n"
+ ":arg rate: The new sample rate.\n"
+ ":type rate: double\n"
+ ":arg high_quality: When true use a higher quality but slower resampler.\n"
+ ":type high_quality: bool\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_resample(Sound* self, PyObject* args)
+{
+ double rate;
+ PyObject* high_qualityo;
+ bool high_quality = false;
+
+ if(!PyArg_ParseTuple(args, "d|O:resample", &rate, &high_qualityo))
+ return nullptr;
+
+ if(!PyBool_Check(high_qualityo))
+ {
+ PyErr_SetString(PyExc_TypeError, "high_quality is not a boolean!");
+ return nullptr;
+ }
+
+ high_quality = high_qualityo == Py_True;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.rate = rate;
+ specs.format = FORMAT_INVALID;
+ if(high_quality)
+ parent->sound = new std::shared_ptr<ISound>(new JOSResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ else
+ parent->sound = new std::shared_ptr<ISound>(new LinearResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_reverse_doc,
+ "reverse()\n\n"
+ "Plays a sound reversed.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The sound 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:`cache` before "
+ "being played reversed.\n\n"
+ ".. warning:: If seeking is not accurate in the underlying sound "
+ "you'll likely hear skips/jumps/cracks.");
+
+static PyObject *
+Sound_reverse(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Reverse(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sum_doc,
+ "sum()\n\n"
+ "Sums the samples of a sound.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sum(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Sum(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_threshold_doc,
+ "threshold(threshold = 0)\n\n"
+ "Makes a threshold wave out of an audio wave by setting all samples "
+ "with a amplitude >= threshold to 1, all <= -threshold to -1 and "
+ "all between to 0.\n\n"
+ ":arg threshold: Threshold value over which an amplitude counts "
+ "non-zero.\n"
+ ":type threshold: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_threshold(Sound* self, PyObject* args)
+{
+ float threshold = 0;
+
+ if(!PyArg_ParseTuple(args, "|f:threshold", &threshold))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Threshold(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), threshold));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_volume_doc,
+ "volume(volume)\n\n"
+ "Changes the volume of a sound.\n\n"
+ ":arg volume: The new volume..\n"
+ ":type volume: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\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 *
+Sound_volume(Sound* self, PyObject* args)
+{
+ float volume;
+
+ if(!PyArg_ParseTuple(args, "f:volume", &volume))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Volume(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), volume));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_join_doc,
+ "join(sound)\n\n"
+ "Plays two factories in sequence.\n\n"
+ ":arg sound: The sound to play second.\n"
+ ":type sound: :class:`Sound`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The two factories have to have the same specifications "
+ "(channels and samplerate).");
+
+static PyObject *
+Sound_join(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object has to be of type Sound!");
+ return nullptr;
+ }
+
+ Sound* parent;
+ Sound* child = (Sound*)object;
+
+ parent = (Sound*)type->tp_alloc(type, 0);
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Double(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ISound>*>(child->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_mix_doc,
+ "mix(sound)\n\n"
+ "Mixes two factories.\n\n"
+ ":arg sound: The sound to mix over the other.\n"
+ ":type sound: :class:`Sound`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The two factories have to have the same specifications "
+ "(channels and samplerate).");
+
+static PyObject *
+Sound_mix(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sound!");
+ return nullptr;
+ }
+
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+ Sound* child = (Sound*)object;
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Superpose(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ISound>*>(child->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
+ "pingpong()\n\n"
+ "Plays a sound forward and then backward.\n"
+ "This is like joining a sound with its reverse.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_pingpong(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new PingPong(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_list_doc,
+ "list()\n\n"
+ "Creates an empty sound list that can contain several sounds.\n\n"
+ ":arg random: wether the playback will be random or not.\n"
+ ":type random: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_list(PyTypeObject* type, PyObject* args)
+{
+ int random;
+
+ if(!PyArg_ParseTuple(args, "i:random", &random))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new SoundList(random));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_mutable_doc,
+ "mutable()\n\n"
+ "Creates a sound that will be restarted when sought backwards.\n"
+ "If the original sound is a sound list, the playing sound can change.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_mutable(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new MutableSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_list_addSound_doc,
+ "addSound(sound)\n\n"
+ "Adds a new sound to a sound list.\n\n"
+ ":arg sound: The sound that will be added to the list.\n"
+ ":type sound: :class:`Sound`\n\n"
+ ".. note:: You can only add a sound to a sound list.");
+
+static PyObject *
+Sound_list_addSound(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object has to be of type Sound!");
+ return nullptr;
+ }
+
+ Sound* child = (Sound*)object;
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<SoundList>*>(self->sound))->addSound(*reinterpret_cast<std::shared_ptr<ISound>*>(child->sound));
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+#ifdef WITH_CONVOLUTION
+
+PyDoc_STRVAR(M_aud_Sound_convolver_doc,
+ "convolver()\n\n"
+ "Creates a sound that will apply convolution to another sound.\n\n"
+ ":arg impulseResponse: The filter with which convolve the sound.\n"
+ ":type impulseResponse: :class:`ImpulseResponse`\n"
+ ":arg threadPool: A thread pool used to parallelize convolution.\n"
+ ":type threadPool: :class:`ThreadPool`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_convolver(Sound* self, PyObject* args)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ PyObject* object1;
+ PyObject* object2;
+
+ if(!PyArg_ParseTuple(args, "OO:convolver", &object1, &object2))
+ return nullptr;
+
+ ImpulseResponseP* filter = checkImpulseResponse(object1);
+ if(!filter)
+ return nullptr;
+
+ ThreadPoolP* threadPool = checkThreadPool(object2);
+ if(!threadPool)
+ return nullptr;
+
+ Sound* parent;
+ parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new ConvolverSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ImpulseResponse>*>(filter->impulseResponse), *reinterpret_cast<std::shared_ptr<ThreadPool>*>(threadPool->threadPool)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_binaural_doc,
+ "convolver()\n\n"
+ "Creates a binaural sound using another sound as source. The original sound must be mono\n\n"
+ ":arg hrtfs: An HRTF set.\n"
+ ":type hrtf: :class:`HRTF`\n"
+ ":arg source: An object representing the source position of the sound.\n"
+ ":type source: :class:`Source`\n"
+ ":arg threadPool: A thread pool used to parallelize convolution.\n"
+ ":type threadPool: :class:`ThreadPool`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_binaural(Sound* self, PyObject* args)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ PyObject* object1;
+ PyObject* object2;
+ PyObject* object3;
+
+ if(!PyArg_ParseTuple(args, "OOO:binaural", &object1, &object2, &object3))
+ return nullptr;
+
+ HRTFP* hrtfs = checkHRTF(object1);
+ if(!hrtfs)
+ return nullptr;
+
+ SourceP* source = checkSource(object2);
+ if(!hrtfs)
+ return nullptr;
+
+ ThreadPoolP* threadPool = checkThreadPool(object3);
+ if(!threadPool)
+ return nullptr;
+
+ Sound* parent;
+ parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new BinauralSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<HRTF>*>(hrtfs->hrtf), *reinterpret_cast<std::shared_ptr<Source>*>(source->source), *reinterpret_cast<std::shared_ptr<ThreadPool>*>(threadPool->threadPool)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+#endif
+
+static PyMethodDef Sound_methods[] = {
+ {"data", (PyCFunction)Sound_data, METH_NOARGS,
+ M_aud_Sound_data_doc
+ },
+ {"write", (PyCFunction)Sound_write, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Sound_write_doc
+ },
+ {"buffer", (PyCFunction)Sound_buffer, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_buffer_doc
+ },
+ {"cache", (PyCFunction)Sound_cache, METH_NOARGS,
+ M_aud_Sound_cache_doc
+ },
+ {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_file_doc
+ },
+ {"sawtooth", (PyCFunction)Sound_sawtooth, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_sawtooth_doc
+ },
+ {"silence", (PyCFunction)Sound_silence, METH_NOARGS | METH_CLASS,
+ M_aud_Sound_silence_doc
+ },
+ {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_sine_doc
+ },
+ {"square", (PyCFunction)Sound_square, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_square_doc
+ },
+ {"triangle", (PyCFunction)Sound_triangle, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_triangle_doc
+ },
+ {"accumulate", (PyCFunction)Sound_accumulate, METH_VARARGS,
+ M_aud_Sound_accumulate_doc
+ },
+ {"ADSR", (PyCFunction)Sound_ADSR, METH_VARARGS,
+ M_aud_Sound_ADSR_doc
+ },
+ {"delay", (PyCFunction)Sound_delay, METH_VARARGS,
+ M_aud_Sound_delay_doc
+ },
+ {"envelope", (PyCFunction)Sound_envelope, METH_VARARGS,
+ M_aud_Sound_envelope_doc
+ },
+ {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS,
+ M_aud_Sound_fadein_doc
+ },
+ {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS,
+ M_aud_Sound_fadeout_doc
+ },
+ {"filter", (PyCFunction)Sound_filter, METH_VARARGS,
+ M_aud_Sound_filter_doc
+ },
+ {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS,
+ M_aud_Sound_highpass_doc
+ },
+ {"limit", (PyCFunction)Sound_limit, METH_VARARGS,
+ M_aud_Sound_limit_doc
+ },
+ {"loop", (PyCFunction)Sound_loop, METH_VARARGS,
+ M_aud_Sound_loop_doc
+ },
+ {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS,
+ M_aud_Sound_lowpass_doc
+ },
+ {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS,
+ M_aud_Sound_pitch_doc
+ },
+ {"rechannel", (PyCFunction)Sound_rechannel, METH_VARARGS,
+ M_aud_Sound_rechannel_doc
+ },
+ {"resample", (PyCFunction)Sound_resample, METH_VARARGS,
+ M_aud_Sound_resample_doc
+ },
+ {"reverse", (PyCFunction)Sound_reverse, METH_NOARGS,
+ M_aud_Sound_reverse_doc
+ },
+ {"sum", (PyCFunction)Sound_sum, METH_NOARGS,
+ M_aud_Sound_sum_doc
+ },
+ {"threshold", (PyCFunction)Sound_threshold, METH_VARARGS,
+ M_aud_Sound_threshold_doc
+ },
+ {"volume", (PyCFunction)Sound_volume, METH_VARARGS,
+ M_aud_Sound_volume_doc
+ },
+ {"join", (PyCFunction)Sound_join, METH_O,
+ M_aud_Sound_join_doc
+ },
+ {"mix", (PyCFunction)Sound_mix, METH_O,
+ M_aud_Sound_mix_doc
+ },
+ { "pingpong", (PyCFunction)Sound_pingpong, METH_NOARGS,
+ M_aud_Sound_pingpong_doc
+ },
+ { "list", (PyCFunction)Sound_list, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_list_doc
+ },
+ { "mutable", (PyCFunction)Sound_mutable, METH_NOARGS,
+ M_aud_Sound_mutable_doc
+ },
+ { "addSound", (PyCFunction)Sound_list_addSound, METH_O,
+ M_aud_Sound_list_addSound_doc
+ },
+#ifdef WITH_CONVOLUTION
+ { "convolver", (PyCFunction)Sound_convolver, METH_VARARGS,
+ M_aud_Sound_convolver_doc
+ },
+ { "binaural", (PyCFunction)Sound_binaural, METH_VARARGS,
+ M_aud_Sound_binaural_doc
+ },
+#endif
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_specs_doc,
+ "The sample specification of the sound as a tuple with rate and channel count.");
+
+static PyObject *
+Sound_get_specs(Sound* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader()->getSpecs();
+ return Py_BuildValue("(di)", specs.rate, specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sound_length_doc,
+ "The sample specification of the sound as a tuple with rate and channel count.");
+
+static PyObject *
+Sound_get_length(Sound* self, void* nothing)
+{
+ try
+ {
+ int length = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader()->getLength();
+ return Py_BuildValue("i", length);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef Sound_properties[] = {
+ {(char*)"specs", (getter)Sound_get_specs, nullptr,
+ M_aud_Sound_specs_doc, nullptr },
+ {(char*)"length", (getter)Sound_get_length, nullptr,
+ M_aud_Sound_length_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_doc,
+ "Sound objects are immutable and represent a sound that can be "
+ "played simultaneously multiple times. They are called factories "
+ "because they create reader objects internally that are used for "
+ "playback.");
+
+PyTypeObject SoundType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Sound", /* tp_name */
+ sizeof(Sound), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Sound_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Sound_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Sound_methods, /* tp_methods */
+ 0, /* tp_members */
+ Sound_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Sound_new, /* tp_new */
+};
+
+AUD_API PyObject* Sound_empty()
+{
+ return SoundType.tp_alloc(&SoundType, 0);
+}
+
+AUD_API Sound* checkSound(PyObject* sound)
+{
+ if(!PyObject_TypeCheck(sound, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sound!");
+ return nullptr;
+ }
+
+ return (Sound*)sound;
+}
+
+
+bool initializeSound()
+{
+ import_array();
+
+ return PyType_Ready(&SoundType) >= 0;
+}
+
+
+void addSoundToModule(PyObject* module)
+{
+ Py_INCREF(&SoundType);
+ PyModule_AddObject(module, "Sound", (PyObject *)&SoundType);
+}
diff --git a/extern/audaspace/bindings/python/PySound.h b/extern/audaspace/bindings/python/PySound.h
new file mode 100644
index 00000000000..657bb2131e6
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySound.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ISound;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ISound* sound;
+} Sound;
+
+extern AUD_API PyObject* Sound_empty();
+extern AUD_API Sound* checkSound(PyObject* sound);
+
+bool initializeSound();
+void addSoundToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySource.cpp b/extern/audaspace/bindings/python/PySource.cpp
new file mode 100644
index 00000000000..a948cf46645
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySource.cpp
@@ -0,0 +1,260 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PySource.h"
+
+#include "Exception.h"
+#include "fx/Source.h"
+
+#include <memory>
+
+extern PyObject* AUDError;
+
+static PyObject *
+Source_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ SourceP* self = (SourceP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ float azimuth, elevation, distance;
+ if(!PyArg_ParseTuple(args, "fff:angles", &azimuth, &elevation, &distance))
+ return nullptr;
+
+ try
+ {
+ self->source = new std::shared_ptr<aud::Source>(new aud::Source(azimuth, elevation, distance));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+Source_dealloc(SourceP* self)
+{
+ if(self->source)
+ delete reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef Source_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Source_azimuth_doc,
+ "The azimuth angle.");
+
+static int
+Source_set_azimuth(SourceP* self, PyObject* args, void* nothing)
+{
+ float azimuth;
+
+ if(!PyArg_Parse(args, "f:azimuth", &azimuth))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setAzimuth(azimuth);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_azimuth(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getAzimuth());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Source_elevation_doc,
+ "The elevation angle.");
+
+static int
+Source_set_elevation(SourceP* self, PyObject* args, void* nothing)
+{
+ float elevation;
+
+ if(!PyArg_Parse(args, "f:elevation", &elevation))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setElevation(elevation);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_elevation(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getElevation());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Source_distance_doc,
+ "The distance value. 0 is min, 1 is max.");
+
+static int
+Source_set_distance(SourceP* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance", &distance))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setDistance(distance);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_distance(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getDistance());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef Source_properties[] = {
+ { (char*)"azimuth", (getter)Source_get_azimuth, (setter)Source_set_azimuth,
+ M_aud_Source_azimuth_doc, nullptr },
+ { (char*)"elevation", (getter)Source_get_elevation, (setter)Source_set_elevation,
+ M_aud_Source_elevation_doc, nullptr },
+ { (char*)"distance", (getter)Source_get_distance, (setter)Source_set_distance,
+ M_aud_Source_distance_doc, nullptr },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Source_doc,
+ "The source object represents the source position of a binaural sound.");
+
+PyTypeObject SourceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Source", /* tp_name */
+ sizeof(SourceP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Source_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Source_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Source_methods, /* tp_methods */
+ 0, /* tp_members */
+ Source_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Source_new, /* tp_new */
+};
+
+AUD_API PyObject* Source_empty()
+{
+ return SourceType.tp_alloc(&SourceType, 0);
+}
+
+
+AUD_API SourceP* checkSource(PyObject* source)
+{
+ if(!PyObject_TypeCheck(source, &SourceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Source!");
+ return nullptr;
+ }
+
+ return (SourceP*)source;
+}
+
+
+bool initializeSource()
+{
+ return PyType_Ready(&SourceType) >= 0;
+}
+
+
+void addSourceToModule(PyObject* module)
+{
+ Py_INCREF(&SourceType);
+ PyModule_AddObject(module, "Source", (PyObject *)&SourceType);
+}
diff --git a/extern/audaspace/bindings/python/PySource.h b/extern/audaspace/bindings/python/PySource.h
new file mode 100644
index 00000000000..19960d80901
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySource.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_Source;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_Source* source;
+} SourceP;
+
+extern AUD_API PyObject* Source_empty();
+extern AUD_API SourceP* checkSource(PyObject* source);
+
+bool initializeSource();
+void addSourceToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyThreadPool.cpp b/extern/audaspace/bindings/python/PyThreadPool.cpp
new file mode 100644
index 00000000000..75811f08273
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyThreadPool.cpp
@@ -0,0 +1,134 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "PyThreadPool.h"
+
+#include "Exception.h"
+#include "util/ThreadPool.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+ThreadPool_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ ThreadPoolP* self = (ThreadPoolP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ unsigned int nThreads;
+ if(!PyArg_ParseTuple(args, "I:nThreads", &nThreads))
+ return nullptr;
+
+ try
+ {
+ self->threadPool = new std::shared_ptr<aud::ThreadPool>(new aud::ThreadPool(nThreads));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+ThreadPool_dealloc(ThreadPoolP* self)
+{
+ if(self->threadPool)
+ delete reinterpret_cast<std::shared_ptr<aud::ThreadPool>*>(self->threadPool);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef ThreadPool_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_ThreadPool_doc,
+ "A ThreadPool is used to parallelize convolution efficiently.");
+
+PyTypeObject ThreadPoolType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.ThreadPool", /* tp_name */
+ sizeof(ThreadPoolP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)ThreadPool_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_ThreadPool_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ ThreadPool_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ThreadPool_new, /* tp_new */
+};
+
+AUD_API PyObject* ThreadPool_empty()
+{
+ return ThreadPoolType.tp_alloc(&ThreadPoolType, 0);
+}
+
+
+AUD_API ThreadPoolP* checkThreadPool(PyObject* threadPool)
+{
+ if(!PyObject_TypeCheck(threadPool, &ThreadPoolType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type ThreadPool!");
+ return nullptr;
+ }
+
+ return (ThreadPoolP*)threadPool;
+}
+
+
+bool initializeThreadPool()
+{
+ return PyType_Ready(&ThreadPoolType) >= 0;
+}
+
+
+void addThreadPoolToModule(PyObject* module)
+{
+ Py_INCREF(&ThreadPoolType);
+ PyModule_AddObject(module, "ThreadPool", (PyObject *)&ThreadPoolType);
+}
diff --git a/extern/audaspace/bindings/python/PyThreadPool.h b/extern/audaspace/bindings/python/PyThreadPool.h
new file mode 100644
index 00000000000..e38d905f52a
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyThreadPool.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ThreadPool;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ThreadPool* threadPool;
+} ThreadPoolP;
+
+extern AUD_API PyObject* ThreadPool_empty();
+extern AUD_API ThreadPoolP* checkThreadPool(PyObject* ThreadPool);
+
+bool initializeThreadPool();
+void addThreadPoolToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/binaural.py b/extern/audaspace/bindings/python/examples/binaural.py
new file mode 100644
index 00000000000..e7a2f6cf6d9
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/binaural.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+import aud, sys, time, multiprocessing
+device = aud.Device()
+hrtf = aud.HRTF().loadLeftHrtfSet(".wav", sys.argv[2])
+threadPool = aud.ThreadPool(multiprocessing.cpu_count())
+source = aud.Source(0, 0, 0)
+sound = aud.Sound.file(sys.argv[1]).rechannel(1).binaural(hrtf, source, threadPool)
+handle = device.play(sound)
+
+while handle.status:
+ source.azimuth += 1
+ print("Azimuth: " + str(source.azimuth))
+ time.sleep(0.1) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/convolution.py b/extern/audaspace/bindings/python/examples/convolution.py
new file mode 100644
index 00000000000..4de25b0336a
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/convolution.py
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+import aud, sys, time, multiprocessing
+device = aud.Device()
+ir = aud.ImpulseResponse(aud.Sound.file(sys.argv[2]))
+threadPool = aud.ThreadPool(multiprocessing.cpu_count())
+sound = aud.Sound.file(sys.argv[1]).convolver(ir, threadPool)
+handle = device.play(sound)
+handle.volume = 0.1
+while handle.status:
+ time.sleep(0.1) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/dynamicmusic.py b/extern/audaspace/bindings/python/examples/dynamicmusic.py
new file mode 100644
index 00000000000..348e2496c0a
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/dynamicmusic.py
@@ -0,0 +1,20 @@
+import aud, sys, time
+
+device=aud.Device()
+dMusic = aud.DynamicMusic(device)
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+effect = aud.Sound.file(sys.argv[3])
+
+dMusic.addScene(sound1)
+dMusic.addScene(sound2)
+dMusic.addTransition(1,2,effect)
+
+dMusic.fadeTime=3
+dMusic.volume=0.5
+
+dMusic.scene=1
+time.sleep(5)
+dMusic.scene=2
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/playbackmanager.py b/extern/audaspace/bindings/python/examples/playbackmanager.py
new file mode 100644
index 00000000000..2aa1c283545
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/playbackmanager.py
@@ -0,0 +1,27 @@
+import aud, sys, time
+
+device=aud.Device()
+manager = aud.PlaybackManager(device)
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+sound3 = aud.Sound.file(sys.argv[3])
+sound4 = aud.Sound.file(sys.argv[4])
+
+manager.play(sound1, 0)
+manager.play(sound2, 0)
+manager.play(sound3, 1)
+manager.play(sound4, 1)
+
+manager.setVolume(0.2, 0)
+time.sleep(5)
+manager.setVolume(0.0, 1)
+time.sleep(5)
+manager.pause(0)
+time.sleep(5)
+manager.setVolume(0.5, 1)
+manager.setVolume(1.0, 0)
+time.sleep(5)
+manager.stop(1)
+manager.resume(0)
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/player.py b/extern/audaspace/bindings/python/examples/player.py
new file mode 100644
index 00000000000..8acf4ac833f
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/player.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+import aud, sys, time
+device = aud.Device()
+sound = aud.Sound.file(sys.argv[1])
+handle = device.play(sound)
+while handle.status:
+ time.sleep(0.1)
diff --git a/extern/audaspace/bindings/python/examples/randomSounds.py b/extern/audaspace/bindings/python/examples/randomSounds.py
new file mode 100644
index 00000000000..113b0921f09
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/randomSounds.py
@@ -0,0 +1,21 @@
+import aud, sys, time
+
+device=aud.Device()
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+sound3 = aud.Sound.file(sys.argv[3])
+sound4 = aud.Sound.file(sys.argv[4])
+list=aud.Sound.list(True)
+
+list.addSound(sound1)
+list.addSound(sound2)
+list.addSound(sound3)
+list.addSound(sound4)
+mutable=aud.Sound.mutable(list)
+
+device.lock()
+handle=device.play(mutable)
+handle.loop_count=2
+device.unlock()
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/simple.py b/extern/audaspace/bindings/python/examples/simple.py
new file mode 100644
index 00000000000..7aa45b41042
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/simple.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+import aud, time
+device = aud.Device()
+sine = aud.Sound.sine(440)
+square = sine.threshold()
+handle = device.play(square)
+time.sleep(3)
diff --git a/extern/audaspace/bindings/python/examples/siren.py b/extern/audaspace/bindings/python/examples/siren.py
new file mode 100644
index 00000000000..071279b162d
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/siren.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+import aud, math, time
+length = 0.5
+fadelength = 0.05
+
+device = aud.Device()
+high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+sound = high.join(low)
+handle = device.play(sound)
+handle.loop_count = -1
+
+start = time.time()
+
+while time.time() - start < 10:
+ angle = time.time() - start
+
+ handle.location = [math.sin(angle), 0, -math.cos(angle)]
+
diff --git a/extern/audaspace/bindings/python/examples/siren2.py b/extern/audaspace/bindings/python/examples/siren2.py
new file mode 100644
index 00000000000..35e1a600581
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/siren2.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+import aud, math, time
+length = 0.5
+fadelength = 0.05
+runtime = 10
+distance = 100
+velocity = 2 * distance / runtime
+
+device = aud.Device()
+high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+sound = high.join(low)
+handle = device.play(sound)
+handle.loop_count = -1
+
+handle.velocity = [velocity, 0, 0]
+
+start = time.time()
+
+while time.time() - start < runtime:
+ location = -distance + velocity * (time.time() - start)
+
+ handle.location = [location, 10, 0]
diff --git a/extern/audaspace/bindings/python/examples/tetris.py b/extern/audaspace/bindings/python/examples/tetris.py
new file mode 100644
index 00000000000..236a6fa59c1
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ sound = None
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ snd = aud.Sound.square(freq, rate)
+ if char == 'p':
+ snd = snd.volume(0)
+ snd = snd.limit(0, length)
+ snd = snd.fadein(0, fadelength)
+ snd = snd.fadeout(length - fadelength, fadelength)
+
+ if sound:
+ sound = sound.join(snd)
+ else:
+ sound = snd
+ return sound
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/examples/tetris2.py b/extern/audaspace/bindings/python/examples/tetris2.py
new file mode 100644
index 00000000000..08708581af6
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris2.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ position = 0
+ sequence = aud.Sequence()
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+ entry = sequence.add(note, position, position + length, 0)
+ if char == 'p':
+ entry.muted = True
+
+ position += length
+
+ return sequence.limit(0, position)
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/examples/tetris3.py b/extern/audaspace/bindings/python/examples/tetris3.py
new file mode 100644
index 00000000000..aa66d5457d3
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris3.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ position = 0
+ sequence = aud.Sequence()
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ if char != 'p':
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+ sequence.add(note, position, position + length, 0)
+
+ position += length
+
+ return sequence.limit(0, position)
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/setup.py.in b/extern/audaspace/bindings/python/setup.py.in
new file mode 100644
index 00000000000..add1a2d1475
--- /dev/null
+++ b/extern/audaspace/bindings/python/setup.py.in
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import os
+import codecs
+import numpy
+
+from distutils.core import setup, Extension
+
+if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
+ import subprocess
+ from distutils.core import Distribution
+ from distutils.command.build import build
+
+ dist = Distribution()
+ cmd = build(dist)
+ cmd.finalize_options()
+ #print(cmd.build_platlib)
+
+ os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
+ os.environ['LD_LIBRARY_PATH'] = os.getcwd()
+
+ ret = subprocess.call(sys.argv[2:])
+ sys.exit(ret)
+
+
+# the following line is not working due to https://bugs.python.org/issue9023
+#source_directory = os.path.relpath('@PYTHON_SOURCE_DIRECTORY@')
+source_directory = '@PYTHON_SOURCE_DIRECTORY@'
+
+extra_args = []
+
+if sys.platform == 'win32':
+ extra_args.append('/EHsc')
+ extra_args.append('/DAUD_BUILD_SHARED_LIBRARY')
+else:
+ extra_args.append('-std=c++11')
+
+audaspace = Extension(
+ 'aud',
+ include_dirs = ['@CMAKE_CURRENT_BINARY_DIR@', '@FFTW_INCLUDE_DIR@', os.path.join(source_directory, '../../include'), numpy.get_include()],
+ libraries = ['audaspace'],
+ library_dirs = ['.', 'Release', 'Debug'],
+ language = 'c++',
+ extra_compile_args = extra_args,
+ sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
+)
+
+setup(
+ name = 'audaspace',
+ version = '@AUDASPACE_LONG_VERSION@',
+ description = 'Audaspace is a high level audio library.',
+ author = 'Jörg Müller',
+ author_email = 'nexyon@gmail.com',
+ url = 'https://github.com/audaspace/audaspace',
+ license = 'Apache License 2.0',
+ long_description = codecs.open(os.path.join(source_directory, '../../README.md'), 'r', 'utf-8').read(),
+ ext_modules = [audaspace],
+ headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
+)
+
diff --git a/extern/audaspace/blender_config.cmake b/extern/audaspace/blender_config.cmake
new file mode 100644
index 00000000000..5b5440920d0
--- /dev/null
+++ b/extern/audaspace/blender_config.cmake
@@ -0,0 +1,26 @@
+set(AUDASPACE_STANDALONE FALSE)
+set(BUILD_DEMOS FALSE)
+set(SHARED_LIBRARY FALSE)
+set(WITH_C TRUE)
+set(WITH_DOCS FALSE)
+set(WITH_FFMPEG ${WITH_CODEC_FFMPEG})
+set(WITH_FFTW FALSE)
+set(WITH_LIBSNDFILE ${WITH_CODEC_SNDFILE})
+set(SEPARATE_C FALSE)
+set(PLUGIN_FFMPEG FALSE)
+set(PLUGIN_JACK FALSE)
+set(PLUGIN_LIBSNDFILE FALSE)
+set(PLUGIN_OPENAL FALSE)
+set(PLUGIN_SDL FALSE)
+set(WITH_PYTHON_MODULE FALSE)
+set(DYNLOAD_JACK ${WITH_JACK_DYNLOAD})
+set(WITH_BINDING_DOCS FALSE)
+set(BLENDER_AUDASPACE TRUE)
+set(FFMPEG_FOUND ${WITH_CODEC_FFMPEG})
+set(JACK_FOUND ${WITH_JACK})
+set(LIBSNDFILE_FOUND ${WITH_CODEC_SNDFILE})
+set(OPENAL_FOUND ${WITH_OPENAL})
+set(PYTHONLIBS_FOUND TRUE)
+set(NUMPY_FOUND TRUE)
+set(NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIRS})
+set(SDL_FOUND ${WITH_SDL})
diff --git a/extern/audaspace/config/Audaspace.h.in b/extern/audaspace/config/Audaspace.h.in
new file mode 100644
index 00000000000..3e6912727b8
--- /dev/null
+++ b/extern/audaspace/config/Audaspace.h.in
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Audaspace.h
+ * @ingroup general
+ * The main header file of the library defining the namespace and basic data types.
+ */
+
+/**
+ * \def AUD_API
+ * Used for exporting symbols in the shared library.
+ */
+
+/**
+ * \def AUD_PLUGIN_API
+ * Used for exporting symbols in the shared library.
+ */
+
+/**
+ * \def AUD_EXPORT_API
+ * Used for using exporting symbols of the shared library.
+ */
+
+/**
+ * \def AUD_USE_API
+ * Used for using exporting symbols of the shared library.
+ */
+
+/**
+ * \def AUD_LOCAL
+ * Used for hiding symbols from export in the shared library.
+ */
+
+// the following two defines and undefines are a hack to silence an error by doxygen
+
+/**
+ * \def AUD_SHARED_LIBRARY
+ * Defined when audaspace was built as a shared library.
+ */
+#define AUD_SHARED_LIBRARY
+#undef AUD_SHARED_LIBRARY
+
+/**
+ * \def AUD_STATIC_LIBRARY
+ * Defined when audaspace was built as a static library.
+ */
+ #define AUD_STATIC_LIBRARY
+ #undef AUD_STATIC_LIBRARY
+
+#define @AUD_LIBRARY_TYPE@
+
+#ifdef _MSC_VER
+ #define AUD_EXPORT_API __declspec(dllexport)
+ #define AUD_USE_API __declspec(dllimport)
+ #define AUD_LOCAL
+#else
+ #ifdef __GNUC__
+ #define AUD_EXPORT_API __attribute__((visibility ("default")))
+ #define AUD_USE_API AUD_EXPORT_API
+ #define AUD_LOCAL __attribute__((visibility ("hidden")))
+ #else
+ #define AUD_EXPORT_API
+ #define AUD_USE_API
+ #define AUD_LOCAL
+ #endif
+#endif
+
+#ifdef AUD_SHARED_LIBRARY
+ #ifdef AUD_BUILD_PLUGIN
+ #define AUD_API AUD_USE_API
+ #define AUD_PLUGIN_API AUD_EXPORT_API
+ #else
+ #ifdef AUD_BUILD_SHARED_LIBRARY
+ #define AUD_API AUD_EXPORT_API
+ #define AUD_PLUGIN_API AUD_EXPORT_API
+ #else
+ #define AUD_API AUD_USE_API
+ #define AUD_PLUGIN_API AUD_USE_API
+ #endif
+ #endif
+#else
+ #define AUD_API
+ #define AUD_PLUGIN_API
+#endif
+
+/// The default playback buffer size of a device.
+#define AUD_DEFAULT_BUFFER_SIZE 1024
+
+#ifdef __cplusplus
+
+/// Opens the audaspace namespace aud.
+#define AUD_NAMESPACE_BEGIN namespace aud {
+
+/// Closes the audaspace namespace aud.
+#define AUD_NAMESPACE_END }
+
+#else
+
+/// Opens the audaspace namespace aud.
+#define AUD_NAMESPACE_BEGIN
+
+/// Closes the audaspace namespace aud.
+#define AUD_NAMESPACE_END
+
+#endif
+
+AUD_NAMESPACE_BEGIN
+
+/// Sample type.(float samples)
+typedef float sample_t;
+
+/// Sample data type (format samples)
+typedef unsigned char data_t;
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/Exception.h b/extern/audaspace/include/Exception.h
new file mode 100644
index 00000000000..b102bfade63
--- /dev/null
+++ b/extern/audaspace/include/Exception.h
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * \def AUD_NOEXCEPT
+ * Compatibility macro for noexcept.
+ */
+#ifdef _MSC_VER
+#define AUD_NOEXCEPT
+#else
+#define AUD_NOEXCEPT noexcept
+#endif
+
+/**
+ * @file Exception.h
+ * @ingroup general
+ * Defines the Exception class as well as the AUD_THROW macro for easy throwing.
+ */
+
+#include "Audaspace.h"
+
+#include <exception>
+#include <string>
+
+/// Throws a Exception with the provided error code.
+#define AUD_THROW(exception, message) { throw exception(message, __FILE__, __LINE__); }
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The Exception class is the general exception base class.
+ */
+class AUD_API Exception : public std::exception
+{
+protected:
+ /// A message describing the problem.
+ const std::string m_message;
+
+ /// The source code file in which the exception was thrown.
+ const std::string m_file;
+
+ /// The source code line from which the exception was thrown.
+ const int m_line;
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ Exception(const Exception& exception);
+
+ /**
+ * Creates a new Exception object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ Exception(std::string message, std::string file, int line);
+public:
+ /**
+ * Destroys the object.
+ */
+ virtual ~Exception() AUD_NOEXCEPT;
+
+ /**
+ * Returns the error message.
+ * @return A C string error message.
+ */
+ virtual const char* what() const AUD_NOEXCEPT;
+
+ /**
+ * Returns the error message plus file and line number for debugging purposes.
+ * @return The error message including debug information.
+ */
+ virtual std::string getDebugMessage() const;
+
+ /**
+ * Returns the error message.
+ * @return The error message as string.
+ */
+ const std::string& getMessage() const;
+
+ /**
+ * Returns the file in which the exception was thrown.
+ * @return The name of the file in which the exception was thrown.
+ */
+ const std::string& getFile() const;
+
+ /**
+ * Returns the line where the exception was originally thrown.
+ * @return The line of the source file where the exception was generated.
+ */
+ int getLine() const;
+};
+
+/**
+ * The FileException class is used for error cases in which files cannot
+ * be read or written due to unknown containers or codecs.
+ */
+class AUD_API FileException : public Exception
+{
+public:
+ /**
+ * Creates a new FileException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ FileException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ FileException(const FileException& exception);
+
+ ~FileException() AUD_NOEXCEPT;
+};
+
+/**
+ * The DeviceException class is used for error cases in connection with
+ * devices, which usually happens when specific features or requests
+ * cannot be fulfilled by a device, for example when the device is opened.
+ */
+class AUD_API DeviceException : public Exception
+{
+public:
+ /**
+ * Creates a new DeviceException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ DeviceException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ DeviceException(const DeviceException& exception);
+
+ ~DeviceException() AUD_NOEXCEPT;
+};
+
+/**
+ * The StateException class is used for error cases of sounds or readers
+ * with illegal states or requirements for states of dependent classes.
+ * It is used for example when an effect reader needs a specific
+ * specification from its input.
+ */
+class AUD_API StateException : public Exception
+{
+public:
+ /**
+ * Creates a new StateException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ StateException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ StateException(const StateException& exception);
+
+ ~StateException() AUD_NOEXCEPT;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_IReader.h b/extern/audaspace/include/IReader.h
index c2c9e607b55..c29900ca579 100644
--- a/intern/audaspace/intern/AUD_IReader.h
+++ b/extern/audaspace/include/IReader.h
@@ -1,48 +1,43 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_IReader.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file IReader.h
+ * @ingroup general
+ * The IReader interface.
+ */
-#ifndef __AUD_IREADER_H__
-#define __AUD_IREADER_H__
+#include "respec/Specification.h"
-#include "AUD_Space.h"
+AUD_NAMESPACE_BEGIN
/**
+ * @interface IReader
* This class represents a sound source as stream or as buffer which can be read
* for example by another reader, a device or whatever.
*/
-class AUD_IReader
+class AUD_API IReader
{
public:
/**
* Destroys the reader.
*/
- virtual ~AUD_IReader() {}
+ virtual ~IReader() {}
/**
* Tells whether the source provides seeking functionality or not.
@@ -77,9 +72,9 @@ public:
/**
* Returns the specification of the reader.
- * \return The AUD_Specs structure.
+ * \return The Specs structure.
*/
- virtual AUD_Specs getSpecs() const=0;
+ virtual Specs getSpecs() const=0;
/**
* Request to read the next length samples out of the source.
@@ -94,4 +89,4 @@ public:
virtual void read(int& length, bool& eos, sample_t* buffer)=0;
};
-#endif //__AUD_IREADER_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/ISound.h b/extern/audaspace/include/ISound.h
new file mode 100644
index 00000000000..c28337e1b4e
--- /dev/null
+++ b/extern/audaspace/include/ISound.h
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ISound.h
+ * @ingroup general
+ * The ISound interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * @interface ISound
+ * This class represents a type of sound source and saves the necessary values
+ * for it. It is able to create a reader that is actually usable for playback
+ * of the respective sound source through the factory method createReader.
+ */
+class AUD_API ISound
+{
+public:
+ /**
+ * Destroys the sound.
+ */
+ virtual ~ISound() {}
+
+ /**
+ * Creates a reader for playback of the sound source.
+ * \return A pointer to an IReader object or nullptr if there has been an
+ * error.
+ * \exception Exception An exception may be thrown if there has been
+ * a more unexpected error during reader creation.
+ */
+ virtual std::shared_ptr<IReader> createReader()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/DefaultSynchronizer.h b/extern/audaspace/include/devices/DefaultSynchronizer.h
new file mode 100644
index 00000000000..31f6c65219c
--- /dev/null
+++ b/extern/audaspace/include/devices/DefaultSynchronizer.h
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DefaultSynchronizer.h
+ * @ingroup devices
+ * The DefaultSynchronizer class.
+ */
+
+#include "ISynchronizer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is a default ISynchronizer implementation that actually does no
+ * synchronization and is intended for devices that don't support it.
+ */
+class AUD_API DefaultSynchronizer : public ISynchronizer
+{
+public:
+ virtual void seek(std::shared_ptr<IHandle> handle, float time);
+ virtual float getPosition(std::shared_ptr<IHandle> handle);
+ virtual void play();
+ virtual void stop();
+ virtual void setSyncCallback(syncFunction function, void* data);
+ virtual int isPlaying();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/DeviceManager.h b/extern/audaspace/include/devices/DeviceManager.h
new file mode 100644
index 00000000000..27a546630e8
--- /dev/null
+++ b/extern/audaspace/include/devices/DeviceManager.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DeviceManager.h
+ * @ingroup devices
+ * The DeviceManager class.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+#include <vector>
+#include <unordered_map>
+
+AUD_NAMESPACE_BEGIN
+
+class IDevice;
+class IDeviceFactory;
+class I3DDevice;
+
+/**
+ * This class manages all device plugins and maintains a device if asked to do so.
+ *
+ * This enables applications to access their output device without having to carry
+ * it through the whole application.
+ */
+class AUD_API DeviceManager
+{
+private:
+ static std::unordered_map<std::string, std::shared_ptr<IDeviceFactory>> m_factories;
+
+ static std::shared_ptr<IDevice> m_device;
+
+ // delete copy constructor and operator=
+ DeviceManager(const DeviceManager&) = delete;
+ DeviceManager& operator=(const DeviceManager&) = delete;
+ DeviceManager() = delete;
+
+public:
+ /**
+ * Registers a device factory.
+ *
+ * This method is mostly used by plugin developers to add their device implementation
+ * for general use by the library end users.
+ * @param name A representative name for the device.
+ * @param factory The factory that creates the device.
+ */
+ static void registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory);
+
+ /**
+ * Returns the factory for a specific device.
+ * @param name The representative name of the device.
+ * @return The factory if it was found, or nullptr otherwise.
+ */
+ static std::shared_ptr<IDeviceFactory> getDeviceFactory(std::string name);
+
+ /**
+ * Returns the default device based on the priorities of the registered factories.
+ * @return The default device or nullptr if no factory has been registered.
+ */
+ static std::shared_ptr<IDeviceFactory> getDefaultDeviceFactory();
+
+
+ /**
+ * Sets a device that should be handled by the manager.
+ *
+ * If a device is currently being handled it will be released.
+ * @param device The device the manager should take care of.
+ */
+ static void setDevice(std::shared_ptr<IDevice> device);
+
+ /**
+ * Opens a device which will then be handled by the manager.
+ *
+ * If a device is currently being handled it will be released.
+ * @param name The representative name of the device.
+ */
+ static void openDevice(std::string name);
+
+ /**
+ * Opens the default device which will then be handled by the manager.
+ *
+ * The device to open is selected based on the priority of the registered factories.
+ * If a device is currently being handled it will be released.
+ */
+ static void openDefaultDevice();
+
+ /**
+ * Releases the currently handled device.
+ */
+ static void releaseDevice();
+
+ /**
+ * Returns the currently handled device.
+ * @return The handled device or nullptr if no device has been registered.
+ */
+ static std::shared_ptr<IDevice> getDevice();
+
+ /**
+ * Returns the currently handled 3D device.
+ * @return The handled device or nullptr if no device has been registered
+ * or the registered device is not an I3DDevice.
+ */
+ static std::shared_ptr<I3DDevice> get3DDevice();
+
+ /**
+ * Returns a list of available devices.
+ * @return A list of strings with the names of available devices.
+ */
+ static std::vector<std::string> getAvailableDeviceNames();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/I3DDevice.h b/extern/audaspace/include/devices/I3DDevice.h
new file mode 100644
index 00000000000..f49bbcbb07e
--- /dev/null
+++ b/extern/audaspace/include/devices/I3DDevice.h
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file I3DDevice.h
+ * @ingroup devices
+ * Defines the I3DDevice interface as well as the different distance models.
+ */
+
+#include "util/Math3D.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * Possible distance models for the 3D device.
+ *
+ * The distance models supported are the same as documented in the [OpenAL Specification](http://openal.org/).
+ */
+enum DistanceModel
+{
+ DISTANCE_MODEL_INVALID = 0,
+ DISTANCE_MODEL_INVERSE,
+ DISTANCE_MODEL_INVERSE_CLAMPED,
+ DISTANCE_MODEL_LINEAR,
+ DISTANCE_MODEL_LINEAR_CLAMPED,
+ DISTANCE_MODEL_EXPONENT,
+ DISTANCE_MODEL_EXPONENT_CLAMPED
+};
+
+/**
+ * @interface I3DDevice
+ * The I3DDevice interface represents an output device for 3D sound.
+ *
+ * The interface has been modelled after the OpenAL 1.1 API,
+ * see the [OpenAL Specification](http://openal.org/) for lots of details.
+ */
+class AUD_API I3DDevice
+{
+public:
+ /**
+ * Retrieves the listener location.
+ * \return The listener location.
+ */
+ virtual Vector3 getListenerLocation() const=0;
+
+ /**
+ * Sets the listener location.
+ * \param location The new location.
+ * \note The location is not updated with the velocity and
+ * remains constant until the next call of this method.
+ */
+ virtual void setListenerLocation(const Vector3& location)=0;
+
+ /**
+ * Retrieves the listener velocity.
+ * \return The listener velocity.
+ */
+ virtual Vector3 getListenerVelocity() const=0;
+
+ /**
+ * Sets the listener velocity.
+ * \param velocity The new velocity.
+ * \note This velocity does not change the position of the listener
+ * over time, it is simply used for the calculation of the doppler effect.
+ */
+ virtual void setListenerVelocity(const Vector3& velocity)=0;
+
+ /**
+ * Retrieves the listener orientation.
+ * \return The listener orientation as quaternion.
+ */
+ virtual Quaternion getListenerOrientation() const=0;
+
+ /**
+ * Sets the listener orientation.
+ * \param orientation The new orientation as quaternion.
+ * \note The coordinate system used is right handed and the listener
+ * by default is oriented looking in the negative z direction with the
+ * positive y axis as up direction.
+ */
+ virtual void setListenerOrientation(const Quaternion& orientation)=0;
+
+
+ /**
+ * Retrieves the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \return The speed of sound.
+ */
+ virtual float getSpeedOfSound() const=0;
+
+ /**
+ * Sets the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \param speed The new speed of sound.
+ */
+ virtual void setSpeedOfSound(float speed)=0;
+
+ /**
+ * Retrieves the doppler factor.
+ * This value is a scaling factor for the velocity vectors of sources and
+ * listener which is used while calculating the doppler effect.
+ * \return The doppler factor.
+ */
+ virtual float getDopplerFactor() const=0;
+
+ /**
+ * Sets the doppler factor.
+ * This value is a scaling factor for the velocity vectors of sources and
+ * listener which is used while calculating the doppler effect.
+ * \param factor The new doppler factor.
+ */
+ virtual void setDopplerFactor(float factor)=0;
+
+ /**
+ * Retrieves the distance model.
+ * \return The distance model.
+ */
+ virtual DistanceModel getDistanceModel() const=0;
+
+ /**
+ * Sets the distance model.
+ * \param model distance model.
+ */
+ virtual void setDistanceModel(DistanceModel model)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_I3DHandle.h b/extern/audaspace/include/devices/I3DHandle.h
index 69ca985630a..2ff29f9bd21 100644
--- a/intern/audaspace/intern/AUD_I3DHandle.h
+++ b/extern/audaspace/include/devices/I3DHandle.h
@@ -1,87 +1,94 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_I3DHandle.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file I3DHandle.h
+ * @ingroup devices
+ * The I3DHandle interface.
+ */
-#ifndef __AUD_I3DHANDLE_H__
-#define __AUD_I3DHANDLE_H__
+#include "util/Math3D.h"
-#include "AUD_Space.h"
-#include "AUD_3DMath.h"
+AUD_NAMESPACE_BEGIN
/**
- * This class represents a playback handle for 3D sources.
+ * @interface I3DHandle
+ * The I3DHandle interface represents a playback handle for 3D sources.
+ * If the playback IDevice class also implements the I3DDevice interface
+ * then all playback IHandle instances also implement this interface.
+ *
+ * The interface has been modelled after the OpenAL 1.1 API,
+ * see the [OpenAL Specification](http://openal.org/) for lots of details.
*/
-class AUD_I3DHandle
+class AUD_API I3DHandle
{
public:
/**
* Destroys the handle.
*/
- virtual ~AUD_I3DHandle() {}
+ virtual ~I3DHandle() {}
/**
- * Retrieves the location of a source.
+ * Retrieves the location of the source.
* \return The location.
*/
- virtual AUD_Vector3 getSourceLocation()=0;
+ virtual Vector3 getLocation()=0;
/**
- * Sets the location of a source.
+ * Sets the location of the source.
* \param location The new location.
* \return Whether the action succeeded.
+ * \note The location is not updated with the velocity and
+ * remains constant until the next call of this method.
*/
- virtual bool setSourceLocation(const AUD_Vector3& location)=0;
+ virtual bool setLocation(const Vector3& location)=0;
/**
- * Retrieves the velocity of a source.
+ * Retrieves the velocity of the source.
* \return The velocity.
*/
- virtual AUD_Vector3 getSourceVelocity()=0;
+ virtual Vector3 getVelocity()=0;
/**
- * Sets the velocity of a source.
+ * Sets the velocity of the source.
* \param velocity The new velocity.
* \return Whether the action succeeded.
+ * \note This velocity does not change the position of the listener
+ * over time, it is simply used for the calculation of the doppler effect.
*/
- virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
+ virtual bool setVelocity(const Vector3& velocity)=0;
/**
- * Retrieves the orientation of a source.
+ * Retrieves the orientation of the source.
* \return The orientation as quaternion.
*/
- virtual AUD_Quaternion getSourceOrientation()=0;
+ virtual Quaternion getOrientation()=0;
/**
- * Sets the orientation of a source.
+ * Sets the orientation of the source.
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
+ * \note The coordinate system used is right handed and the source
+ * by default is oriented looking in the negative z direction with the
+ * positive y axis as up direction.
+ * \note This setting currently only affects sounds with non-default cone settings.
*/
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
+ virtual bool setOrientation(const Quaternion& orientation)=0;
/**
@@ -96,6 +103,7 @@ public:
* to the listener.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
+ * \note The default value is true as this setting is used to play sounds ordinarily without 3D.
*/
virtual bool setRelative(bool relative)=0;
@@ -170,28 +178,34 @@ public:
virtual bool setAttenuation(float factor)=0;
/**
- * Retrieves the outer angle of the cone of a source.
+ * Retrieves the outer opening angle of the cone of a source.
* \return The outer angle of the cone.
+ * \note This angle is defined in degrees.
*/
virtual float getConeAngleOuter()=0;
/**
- * Sets the outer angle of the cone of a source.
+ * Sets the outer opening angle of the cone of a source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
+ * \note This angle is defined in degrees.
*/
virtual bool setConeAngleOuter(float angle)=0;
/**
- * Retrieves the inner angle of the cone of a source.
+ * Retrieves the inner opening angle of the cone of a source.
+ * The volume inside this cone is unaltered.
* \return The inner angle of the cone.
+ * \note This angle is defined in degrees.
*/
virtual float getConeAngleInner()=0;
/**
- * Sets the inner angle of the cone of a source.
+ * Sets the inner opening angle of the cone of a source.
+ * The volume inside this cone is unaltered.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
+ * \note This angle is defined in degrees.
*/
virtual bool setConeAngleInner(float angle)=0;
@@ -200,6 +214,7 @@ public:
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \return The outer volume of the cone.
+ * \note The general volume of the handle still applies on top of this.
*/
virtual float getConeVolumeOuter()=0;
@@ -209,8 +224,9 @@ public:
* volume and this value.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
+ * \note The general volume of the handle still applies on top of this.
*/
virtual bool setConeVolumeOuter(float volume)=0;
};
-#endif //__AUD_I3DHANDLE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/IDevice.h b/extern/audaspace/include/devices/IDevice.h
new file mode 100644
index 00000000000..92a85d900e2
--- /dev/null
+++ b/extern/audaspace/include/devices/IDevice.h
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDevice.h
+ * @ingroup devices
+ * The IDevice interface.
+ */
+
+#include "respec/Specification.h"
+#include "util/ILockable.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IHandle;
+class IReader;
+class ISound;
+class ISynchronizer;
+
+/**
+ * @interface IDevice
+ * The IDevice interface represents an output device for sound sources.
+ * Output devices may be several backends such as plattform independand like
+ * SDL or OpenAL or plattform specific like ALSA, but they may also be
+ * files, RAM buffers or other types of streams.
+ * \warning Thread safety must be insured so that no reader is beeing called
+ * twice at the same time.
+ */
+class IDevice : public ILockable
+{
+public:
+ /**
+ * Destroys the device.
+ */
+ virtual ~IDevice() {}
+
+ /**
+ * Returns the specification of the device.
+ */
+ virtual DeviceSpecs getSpecs() const=0;
+
+ /**
+ * Plays a sound source.
+ * \param reader The reader to play.
+ * \param keep When keep is true the sound source will not be deleted but
+ * set to paused when its end has been reached.
+ * \return Returns a handle with which the playback can be controlled.
+ * This is nullptr if the sound couldn't be played back.
+ * \exception Exception Thrown if there's an unexpected (from the
+ * device side) error during creation of the reader.
+ */
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false)=0;
+
+ /**
+ * Plays a sound source.
+ * \param sound The sound to create the reader for the sound source.
+ * \param keep When keep is true the sound source will not be deleted but
+ * set to paused when its end has been reached.
+ * \return Returns a handle with which the playback can be controlled.
+ * This is nullptr if the sound couldn't be played back.
+ * \exception Exception Thrown if there's an unexpected (from the
+ * device side) error during creation of the reader.
+ */
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false)=0;
+
+ /**
+ * Stops all playing sounds.
+ */
+ virtual void stopAll()=0;
+
+ /**
+ * Locks the device.
+ * Used to make sure that between lock and unlock, no buffers are read, so
+ * that it is possible to start, resume, pause, stop or seek several
+ * playback handles simultaneously.
+ * \warning Make sure the locking time is as small as possible to avoid
+ * playback delays that result in unexpected noise and cracks.
+ */
+ virtual void lock()=0;
+
+ /**
+ * Unlocks the previously locked device.
+ */
+ virtual void unlock()=0;
+
+ /**
+ * Retrieves the overall device volume.
+ * \return The overall device volume.
+ */
+ virtual float getVolume() const=0;
+
+ /**
+ * Sets the overall device volume.
+ * \param volume The overall device volume.
+ */
+ virtual void setVolume(float volume)=0;
+
+ /**
+ * Retrieves the synchronizer for this device, which enables accurate synchronization
+ * between audio playback and video playback for example.
+ * @return The synchronizer which will be the DefaultSynchronizer if synchonization is not supported.
+ */
+ virtual ISynchronizer* getSynchronizer()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/IDeviceFactory.h b/extern/audaspace/include/devices/IDeviceFactory.h
new file mode 100644
index 00000000000..6a0f4537b13
--- /dev/null
+++ b/extern/audaspace/include/devices/IDeviceFactory.h
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDeviceFactory.h
+ * @ingroup devices
+ * The IDeviceFactory interface.
+ */
+
+#include "respec/Specification.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IDeviceFactory
+ * The IDeviceFactory interface opens an output device.
+ */
+class AUD_API IDeviceFactory
+{
+public:
+ /**
+ * Opens an audio device for playback.
+ * \exception Exception Thrown if the audio device cannot be opened.
+ */
+ virtual std::shared_ptr<IDevice> openDevice()=0;
+
+ /**
+ * Returns the priority of the device to be the default device for a system.
+ * The higher the priority the more likely it is for this device to be used as the default device.
+ * \return Priority to be the default device.
+ */
+ virtual int getPriority()=0;
+
+ /**
+ * Sets the wanted device specifications for opening the device.
+ * \param specs The wanted audio specification.
+ */
+ virtual void setSpecs(DeviceSpecs specs)=0;
+
+ /**
+ * Sets the size for the internal playback buffers.
+ * The bigger the buffersize, the less likely clicks happen,
+ * but the latency increases too.
+ * \param buffersize The size of the internal buffer.
+ */
+ virtual void setBufferSize(int buffersize)=0;
+
+ /**
+ * Sets a name for the device.
+ * \param name The internal name for the device.
+ */
+ virtual void setName(std::string name)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_IHandle.h b/extern/audaspace/include/devices/IHandle.h
index c80fb4027b8..3f42fc33c3a 100644
--- a/intern/audaspace/intern/AUD_IHandle.h
+++ b/extern/audaspace/include/devices/IHandle.h
@@ -1,49 +1,57 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
-/** \file audaspace/intern/AUD_IHandle.h
- * \ingroup audaspaceintern
+/**
+ * @file IHandle.h
+ * @ingroup devices
+ * Defines the IHandle interface as well as possible states of the handle.
*/
-#ifndef __AUD_IHANDLE_H__
-#define __AUD_IHANDLE_H__
+#include "Audaspace.h"
-//#include "AUD_Space.h"
-//#include "AUD_Reference.h"
+AUD_NAMESPACE_BEGIN
+/// Status of a playback handle.
+enum Status
+{
+ STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
+ STATUS_PLAYING, /// Sound is playing.
+ STATUS_PAUSED, /// Sound is being paused.
+ STATUS_STOPPED /// Sound is stopped but kept in the device.
+};
+
+/**
+ * The stopCallback is called when a handle reaches the end of the stream and
+ * thus gets stopped. A user defined pointer is supplied to the callback.
+ */
typedef void (*stopCallback)(void*);
/**
- * This class represents a playback handles for specific devices.
+ * @interface IHandle
+ * The IHandle interface represents a playback handles of a specific device.
*/
-class AUD_IHandle
+class AUD_API IHandle
{
public:
/**
* Destroys the handle.
*/
- virtual ~AUD_IHandle() {}
+ virtual ~IHandle() {}
/**
* Pauses a played back sound.
@@ -109,15 +117,15 @@ public:
/**
* Returns the status of a played back sound.
* \return
- * - AUD_STATUS_INVALID if the sound has stopped or the handle is
+ * - STATUS_INVALID if the sound has stopped or the handle is
*. invalid
- * - AUD_STATUS_PLAYING if the sound is currently played back.
- * - AUD_STATUS_PAUSED if the sound is currently paused.
- * - AUD_STATUS_STOPPED if the sound finished playing and is still
+ * - STATUS_PLAYING if the sound is currently played back.
+ * - STATUS_PAUSED if the sound is currently paused.
+ * - STATUS_STOPPED if the sound finished playing and is still
* kept in the device.
- * \see AUD_Status
+ * \see Status
*/
- virtual AUD_Status getStatus()=0;
+ virtual Status getStatus()=0;
/**
* Retrieves the volume of a playing sound.
@@ -178,4 +186,4 @@ public:
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
};
-#endif //AUD_IHandle
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/ISynchronizer.h b/extern/audaspace/include/devices/ISynchronizer.h
new file mode 100644
index 00000000000..6f14de59565
--- /dev/null
+++ b/extern/audaspace/include/devices/ISynchronizer.h
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ISynchronizer.h
+ * @ingroup devices
+ * The ISynchronizer interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IHandle;
+
+/**
+ * @interface ISynchronizer
+ * This class enables global synchronization of several audio applications if supported.
+ * JACK for example supports synchronization through JACK Transport.
+ */
+class AUD_API ISynchronizer
+{
+public:
+ /**
+ * Destroys the synchronizer.
+ */
+ virtual ~ISynchronizer() {}
+
+ /**
+ * The syncFunction is called when a synchronization event happens.
+ * The function awaits three parameters. The first one is a user defined
+ * pointer, the second informs about whether playback is on and the third
+ * is the current playback time in seconds.
+ */
+ typedef void (*syncFunction)(void*, int, float);
+
+ /**
+ * Sets the playback position of a handle and the synchronizer to a specific time.
+ * @param handle The handle that should be synchronized/seeked.
+ * @param time The absolute time to synchronize to.
+ */
+ virtual void seek(std::shared_ptr<IHandle> handle, float time) = 0;
+
+ /**
+ * Retrieves the position of the synchronizer.
+ * @param handle The handle which is synchronized.
+ * @return The position in seconds.
+ */
+ virtual float getPosition(std::shared_ptr<IHandle> handle) = 0;
+
+ /**
+ * Starts the synchronizer playback.
+ */
+ virtual void play() = 0;
+
+ /**
+ * Stops the synchronizer playback.
+ */
+ virtual void stop() = 0;
+
+ /**
+ * Sets the callback function that is called when a synchronization event happens.
+ * @param function The function to be called.
+ * @param data User data to be passed to the callback.
+ */
+ virtual void setSyncCallback(syncFunction function, void* data) = 0;
+
+ /**
+ * Retrieves whether the synchronizer is playing back.
+ * @return Whether the synchronizer plays back.
+ */
+ virtual int isPlaying() = 0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/NULLDevice.h b/extern/audaspace/include/devices/NULLDevice.h
new file mode 100644
index 00000000000..76211a799b9
--- /dev/null
+++ b/extern/audaspace/include/devices/NULLDevice.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file NULLDevice.h
+ * @ingroup devices
+ * The NULLDevice class.
+ */
+
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * This device plays nothing.
+ * It is similar to the linux device /dev/null.
+ */
+class AUD_API NULLDevice : public IDevice
+{
+private:
+ class AUD_LOCAL NULLHandle : public IHandle
+ {
+ private:
+ // delete copy constructor and operator=
+ NULLHandle(const NULLHandle&) = delete;
+ NULLHandle& operator=(const NULLHandle&) = delete;
+
+ public:
+
+ NULLHandle();
+
+ virtual ~NULLHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+ };
+
+ // delete copy constructor and operator=
+ NULLDevice(const NULLDevice&) = delete;
+ NULLDevice& operator=(const NULLDevice&) = delete;
+
+public:
+ /**
+ * Creates a new NULLDevice.
+ */
+ NULLDevice();
+
+ virtual ~NULLDevice();
+
+ virtual DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
+ virtual void stopAll();
+ virtual void lock();
+ virtual void unlock();
+ virtual float getVolume() const;
+ virtual void setVolume(float volume);
+ virtual ISynchronizer* getSynchronizer();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/ReadDevice.h b/extern/audaspace/include/devices/ReadDevice.h
new file mode 100644
index 00000000000..b56bd8ce5c4
--- /dev/null
+++ b/extern/audaspace/include/devices/ReadDevice.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ReadDevice.h
+ * @ingroup devices
+ * The ReadDevice class.
+ */
+
+#include "devices/SoftwareDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This device enables to let the user read raw data out of it.
+ */
+class AUD_API ReadDevice : public SoftwareDevice
+{
+private:
+ /**
+ * Whether the device is currently playing back.
+ */
+ bool m_playing;
+
+ // delete copy constructor and operator=
+ ReadDevice(const ReadDevice&) = delete;
+ ReadDevice& operator=(const ReadDevice&) = delete;
+
+protected:
+ virtual void AUD_LOCAL playing(bool playing);
+
+public:
+ /**
+ * Creates a new read device.
+ * \param specs The wanted audio specification.
+ */
+ ReadDevice(DeviceSpecs specs);
+
+ /**
+ * Creates a new read device.
+ * \param specs The wanted audio specification.
+ */
+ ReadDevice(Specs specs);
+
+ /**
+ * Closes the device.
+ */
+ virtual ~ReadDevice();
+
+ /**
+ * Reads the next bytes into the supplied buffer.
+ * \param buffer The target buffer.
+ * \param length The length in samples to be filled.
+ * \return True if the reading succeeded, false if there are no sounds
+ * played back currently, in that case the buffer is filled with
+ * silence.
+ */
+ bool read(data_t* buffer, int length);
+
+ /**
+ * Changes the output specification.
+ * \param specs The new audio data specification.
+ */
+ void changeSpecs(Specs specs);
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/extern/audaspace/include/devices/SoftwareDevice.h
index 54e49c87b27..8f3846394c6 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/extern/audaspace/include/devices/SoftwareDevice.h
@@ -1,74 +1,76 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
-/** \file audaspace/intern/AUD_SoftwareDevice.h
- * \ingroup audaspaceintern
+/**
+ * @file SoftwareDevice.h
+ * @ingroup devices
+ * The SoftwareDevice class.
*/
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "devices/I3DHandle.h"
+#include "devices/DefaultSynchronizer.h"
+#include "util/Buffer.h"
-#ifndef __AUD_SOFTWAREDEVICE_H__
-#define __AUD_SOFTWAREDEVICE_H__
+#include <list>
+#include <mutex>
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_Mixer.h"
-#include "AUD_Buffer.h"
-#include "AUD_PitchReader.h"
-#include "AUD_ResampleReader.h"
-#include "AUD_ChannelMapperReader.h"
+AUD_NAMESPACE_BEGIN
-#include <list>
-#include <pthread.h>
+class Mixer;
+class PitchReader;
+class ResampleReader;
+class ChannelMapperReader;
/**
- * This device plays is a generic device with software mixing.
+ * The software device is a generic device with software mixing.
+ * It is a base class for all software mixing classes.
* Classes implementing this have to:
* - Implement the playing function.
* - Prepare the m_specs, m_mixer variables.
* - Call the create and destroy functions.
* - Call the mix function to retrieve their audio data.
*/
-class AUD_SoftwareDevice : public AUD_IDevice, public AUD_I3DDevice
+class AUD_API SoftwareDevice : public IDevice, public I3DDevice
{
protected:
/// Saves the data for playback.
- class AUD_SoftwareHandle : public AUD_IHandle, public AUD_I3DHandle
+ class AUD_API SoftwareHandle : public IHandle, public I3DHandle
{
+ private:
+ // delete copy constructor and operator=
+ SoftwareHandle(const SoftwareHandle&) = delete;
+ SoftwareHandle& operator=(const SoftwareHandle&) = delete;
+
public:
/// The reader source.
- boost::shared_ptr<AUD_IReader> m_reader;
+ std::shared_ptr<IReader> m_reader;
/// The pitch reader in between.
- boost::shared_ptr<AUD_PitchReader> m_pitch;
+ std::shared_ptr<PitchReader> m_pitch;
/// The resample reader in between.
- boost::shared_ptr<AUD_ResampleReader> m_resampler;
+ std::shared_ptr<ResampleReader> m_resampler;
/// The channel mapper reader in between.
- boost::shared_ptr<AUD_ChannelMapperReader> m_mapper;
+ std::shared_ptr<ChannelMapperReader> m_mapper;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -84,19 +86,21 @@ protected:
/// The calculated final volume of the source.
float m_volume;
+
+ /// The previous calculated final volume of the source.
float m_old_volume;
/// The loop count of the source.
int m_loopcount;
/// Location in 3D Space.
- AUD_Vector3 m_location;
+ Vector3 m_location;
/// Velocity in 3D Space.
- AUD_Vector3 m_velocity;
+ Vector3 m_velocity;
/// Orientation in 3D Space.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Whether the position to the listener is relative or absolute
bool m_relative;
@@ -135,15 +139,19 @@ protected:
void* m_stop_data;
/// Current status of the handle
- AUD_Status m_status;
+ Status m_status;
/// Own device.
- AUD_SoftwareDevice* m_device;
+ SoftwareDevice* m_device;
+ /**
+ * This method is for internal use only.
+ * @param keep Whether the sound should be marked stopped or paused.
+ * @return Whether the action succeeded.
+ */
bool pause(bool keep);
public:
-
/**
* Creates a new software handle.
* \param device The device this handle is from.
@@ -153,7 +161,7 @@ protected:
* \param mapper The channel mapping reader.
* \param keep Whether to keep the handle when the sound ends.
*/
- AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep);
+ SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep);
/**
* Updates the handle's playback parameters.
@@ -162,11 +170,11 @@ protected:
/**
* Sets the audio output specification of the readers.
- * \param sepcs The output specification.
+ * \param specs The output specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(Specs specs);
- virtual ~AUD_SoftwareHandle() {}
+ virtual ~SoftwareHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
@@ -174,7 +182,7 @@ protected:
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
- virtual AUD_Status getStatus();
+ virtual Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
@@ -183,12 +191,12 @@ protected:
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- virtual AUD_Vector3 getSourceLocation();
- virtual bool setSourceLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity();
- virtual bool setSourceVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation();
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual Vector3 getLocation();
+ virtual bool setLocation(const Vector3& location);
+ virtual Vector3 getVelocity();
+ virtual bool setVelocity(const Vector3& velocity);
+ virtual Quaternion getOrientation();
+ virtual bool setOrientation(const Quaternion& orientation);
virtual bool isRelative();
virtual bool setRelative(bool relative);
virtual float getVolumeMaximum();
@@ -209,17 +217,15 @@ protected:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<boost::shared_ptr<AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
-
/**
* The specification of the device.
*/
- AUD_DeviceSpecs m_specs;
+ DeviceSpecs m_specs;
/**
* The mixer.
*/
- boost::shared_ptr<AUD_Mixer> m_mixer;
+ std::shared_ptr<Mixer> m_mixer;
/**
* Whether to do high or low quality resampling.
@@ -251,25 +257,31 @@ protected:
/**
* Sets the audio output specification of the device.
- * \param sepcs The output specification.
+ * \param specs The output specification.
+ */
+ void setSpecs(Specs specs);
+
+ /**
+ * Empty default constructor. To setup the device call the function create()
+ * and to uninitialize call destroy().
*/
- void setSpecs(AUD_Specs specs);
+ SoftwareDevice();
private:
/**
* The reading buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* The list of sounds that are currently playing.
*/
- std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_playingSounds;
+ std::list<std::shared_ptr<SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_pausedSounds;
+ std::list<std::shared_ptr<SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -279,7 +291,7 @@ private:
/**
* The mutex for locking.
*/
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/**
* The overall volume of the device.
@@ -287,13 +299,13 @@ private:
float m_volume;
/// Listener location.
- AUD_Vector3 m_location;
+ Vector3 m_location;
/// Listener velocity.
- AUD_Vector3 m_velocity;
+ Vector3 m_velocity;
/// Listener orientation.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Speed of Sound.
float m_speed_of_sound;
@@ -302,11 +314,18 @@ private:
float m_doppler_factor;
/// Distance model.
- AUD_DistanceModel m_distance_model;
+ DistanceModel m_distance_model;
/// Rendering flags
int m_flags;
+ /// Synchronizer.
+ DefaultSynchronizer m_synchronizer;
+
+ // delete copy constructor and operator=
+ SoftwareDevice(const SoftwareDevice&) = delete;
+ SoftwareDevice& operator=(const SoftwareDevice&) = delete;
+
public:
/**
@@ -314,7 +333,7 @@ public:
* \param handle The handle to set the panning from.
* \param pan The new panning value, should be in the range [-2, 2].
*/
- static void setPanning(AUD_IHandle* handle, float pan);
+ static void setPanning(IHandle* handle, float pan);
/**
* Sets the resampling quality.
@@ -322,27 +341,28 @@ public:
*/
void setQuality(bool quality);
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
+ virtual DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
-
- 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 ISynchronizer* getSynchronizer();
+
+ virtual Vector3 getListenerLocation() const;
+ virtual void setListenerLocation(const Vector3& location);
+ virtual Vector3 getListenerVelocity() const;
+ virtual void setListenerVelocity(const Vector3& velocity);
+ virtual Quaternion getListenerOrientation() const;
+ virtual void setListenerOrientation(const 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 DistanceModel getDistanceModel() const;
+ virtual void setDistanceModel(DistanceModel model);
};
-#endif //__AUD_SOFTWAREDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/File.h b/extern/audaspace/include/file/File.h
new file mode 100644
index 00000000000..24745a757e8
--- /dev/null
+++ b/extern/audaspace/include/file/File.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file File.h
+ * @ingroup file
+ * The File class.
+ */
+
+#include "ISound.h"
+
+#include <string>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * The File sound tries to read a sound file via all available file inputs
+ * that have been registered in the FileManager class.
+ */
+class AUD_API File : public ISound
+{
+private:
+ /**
+ * The filename of the sound source file.
+ */
+ std::string m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ // delete copy constructor and operator=
+ File(const File&) = delete;
+ File& operator=(const File&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * The file is read from the file system using the given path.
+ * \param filename The sound file path.
+ */
+ File(std::string filename);
+
+ /**
+ * Creates a new sound.
+ * The file is read from memory using the supplied buffer.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ File(const data_t* buffer, int size);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/FileManager.h b/extern/audaspace/include/file/FileManager.h
new file mode 100644
index 00000000000..03943ea8ae0
--- /dev/null
+++ b/extern/audaspace/include/file/FileManager.h
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FileManager.h
+ * @ingroup file
+ * The FileManager class.
+ */
+
+#include "respec/Specification.h"
+#include "IWriter.h"
+
+#include <list>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IFileInput;
+class IFileOutput;
+class IReader;
+class Buffer;
+
+/**
+ * The FileManager manages all file input and output plugins.
+ */
+class AUD_API FileManager
+{
+private:
+ static std::list<std::shared_ptr<IFileInput>>& inputs();
+ static std::list<std::shared_ptr<IFileOutput>>& outputs();
+
+ // delete copy constructor and operator=
+ FileManager(const FileManager&) = delete;
+ FileManager& operator=(const FileManager&) = delete;
+ FileManager() = delete;
+
+public:
+ /**
+ * Registers a file input used to create an IReader to read from a file.
+ * @param input The IFileInput to register.
+ */
+ static void registerInput(std::shared_ptr<IFileInput> input);
+
+ /**
+ * Registers a file output used to create an IWriter to write to a file.
+ * @param output The IFileOutput to register.
+ */
+ static void registerOutput(std::shared_ptr<IFileOutput> output);
+
+ /**
+ * Creates a file reader for the given filename if a registed IFileInput is able to read it.
+ * @param filename The path to the file.
+ * @return The reader created.
+ * @exception Exception If no file input can read the file an exception is thrown.
+ */
+ static std::shared_ptr<IReader> createReader(std::string filename);
+
+ /**
+ * Creates a file reader for the given buffer if a registed IFileInput is able to read it.
+ * @param buffer The buffer to read the file from.
+ * @return The reader created.
+ * @exception Exception If no file input can read the file an exception is thrown.
+ */
+ static std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Creates a file writer that writes a sound to the given file path.
+ * Existing files will be overwritten.
+ * @param filename The file path to write to.
+ * @param specs The output specification.
+ * @param format The container format for the file.
+ * @param codec The codec used inside the container.
+ * @param bitrate The bitrate to write with.
+ * @return A writer that creates the file.
+ * @exception Exception If no file output can write the file with the given specification an exception is thrown.
+ */
+ static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/FileWriter.h b/extern/audaspace/include/file/FileWriter.h
new file mode 100644
index 00000000000..dac842f2a8f
--- /dev/null
+++ b/extern/audaspace/include/file/FileWriter.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FileWriter.h
+ * @ingroup file
+ * The FileWriter class.
+ */
+
+#include "respec/Specification.h"
+#include "file/IWriter.h"
+
+#include <string>
+#include <vector>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * The FileWriter class is able to create IWriter classes as well as write readers to them.
+ */
+class AUD_API FileWriter
+{
+private:
+ // hide default constructor, copy constructor and operator=
+ FileWriter() = delete;
+ FileWriter(const FileWriter&) = delete;
+ FileWriter& operator=(const FileWriter&) = delete;
+
+public:
+ /**
+ * Creates a new IWriter.
+ * \param filename The file to write to.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return The writer to write data to.
+ */
+ static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Writes a reader to a writer.
+ * \param reader The reader to read from.
+ * \param writer The writer to write to.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
+ */
+ static void writeReader(std::shared_ptr<IReader> reader, std::shared_ptr<IWriter> writer, unsigned int length, unsigned int buffersize);
+
+ /**
+ * Writes a reader to several writers.
+ * \param reader The reader to read from.
+ * \param writers The writers to write to.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
+ */
+ static void writeReader(std::shared_ptr<IReader> reader, std::vector<std::shared_ptr<IWriter> >& writers, unsigned int length, unsigned int buffersize);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IFileInput.h b/extern/audaspace/include/file/IFileInput.h
new file mode 100644
index 00000000000..bb016a88602
--- /dev/null
+++ b/extern/audaspace/include/file/IFileInput.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IFileInput.h
+ * @ingroup file
+ * The IFileInput interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+class Buffer;
+
+/**
+ * @interface IFileInput
+ * The IFileInput interface represents a file input plugin that can create file
+ * input readers from filenames or buffers.
+ */
+class AUD_API IFileInput
+{
+public:
+ /**
+ * Creates a reader for a file to be read.
+ * \param filename Path to the file to be read.
+ * \return The reader that reads the file.
+ * \exception Exception Thrown if the file specified cannot be read.
+ */
+ virtual std::shared_ptr<IReader> createReader(std::string filename)=0;
+
+ /**
+ * Creates a reader for a file to be read from memory.
+ * \param buffer The in-memory file buffer.
+ * \return The reader that reads the file.
+ * \exception Exception Thrown if the file specified cannot be read.
+ */
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IFileOutput.h b/extern/audaspace/include/file/IFileOutput.h
new file mode 100644
index 00000000000..5a6efacfe94
--- /dev/null
+++ b/extern/audaspace/include/file/IFileOutput.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IFileOutput.h
+ * @ingroup file
+ * The IFileOutput interface.
+ */
+
+#include "file/IWriter.h"
+#include "respec/Specification.h"
+
+#include <memory>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IFileOutput
+ * The IFileOutput interface represents a file output plugin that can write files.
+ */
+class AUD_API IFileOutput
+{
+public:
+ /**
+ * Creates a new file writer.
+ * \param filename The path to the file to be written.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified cannot be written.
+ */
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IWriter.h b/extern/audaspace/include/file/IWriter.h
new file mode 100644
index 00000000000..96decdda391
--- /dev/null
+++ b/extern/audaspace/include/file/IWriter.h
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IWriter.h
+ * @ingroup file
+ * Defines the IWriter interface as well as Container and Codec types.
+ */
+
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/// Container formats for writers.
+enum Container
+{
+ CONTAINER_INVALID = 0,
+ CONTAINER_AC3,
+ CONTAINER_FLAC,
+ CONTAINER_MATROSKA,
+ CONTAINER_MP2,
+ CONTAINER_MP3,
+ CONTAINER_OGG,
+ CONTAINER_WAV
+};
+
+/// Audio codecs for writers.
+enum Codec
+{
+ CODEC_INVALID = 0,
+ CODEC_AAC,
+ CODEC_AC3,
+ CODEC_FLAC,
+ CODEC_MP2,
+ CODEC_MP3,
+ CODEC_PCM,
+ CODEC_VORBIS,
+ CODEC_OPUS
+};
+
+/**
+ * @interface IWriter
+ * This class represents a sound sink where audio data can be written to.
+ */
+class AUD_API IWriter
+{
+public:
+ /**
+ * Destroys the writer.
+ */
+ virtual ~IWriter() {}
+
+ /**
+ * Returns how many samples have been written so far.
+ * \return The writing position as sample count. May be negative if unknown.
+ */
+ virtual int getPosition() const=0;
+
+ /**
+ * Returns the specification of the audio data being written into the sink.
+ * \return The DeviceSpecs structure.
+ * \note Regardless of the format the input still has to be float!
+ */
+ virtual DeviceSpecs getSpecs() const=0;
+
+ /**
+ * Request to write the next length samples out into the sink.
+ * \param length The count of samples to write.
+ * \param buffer The pointer to the buffer containing the data.
+ */
+ virtual void write(unsigned int length, sample_t* buffer)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ADSR.h b/extern/audaspace/include/fx/ADSR.h
new file mode 100644
index 00000000000..c453f2477e1
--- /dev/null
+++ b/extern/audaspace/include/fx/ADSR.h
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ADSR.h
+ * @ingroup fx
+ * The ADSR class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The ADSR effect implements the Attack-Delay-Sustain-Release behaviour of a sound.
+ */
+class AUD_API ADSR : public Effect
+{
+private:
+ /**
+ * Attack time.
+ */
+ float m_attack;
+
+ /**
+ * Decay time.
+ */
+ float m_decay;
+
+ /**
+ * Sustain level.
+ */
+ float m_sustain;
+
+ /**
+ * Release time.
+ */
+ float m_release;
+
+ // delete copy constructor and operator=
+ ADSR(const ADSR&) = delete;
+ ADSR& operator=(const ADSR&) = delete;
+
+public:
+ /**
+ * Creates a new ADSR object.
+ * @param sound The sound to apply this effect to.
+ * @param attack The attack time in seconds.
+ * @param decay The decay time in seconds.
+ * @param sustain The sustain level as linear volume.
+ * @param release The release time in seconds.
+ */
+ ADSR(std::shared_ptr<ISound> sound, float attack, float decay, float sustain, float release);
+
+ /**
+ * Returns the attack time.
+ * @return The attack time in seconds.
+ */
+ float getAttack() const;
+
+ /**
+ * Sets the attack time.
+ * @param attack The attack time in seconds.
+ */
+ void setAttack(float attack);
+
+ /**
+ * Returns the decay time.
+ * @return The decay time in seconds.
+ */
+ float getDecay() const;
+
+ /**
+ * Sets the decay time.
+ * @param decay The decay time in seconds.
+ */
+ void setDecay(float decay);
+
+ /**
+ * Returns the sustain level.
+ * @return The sustain level in linear volume.
+ */
+ float getSustain() const;
+
+ /**
+ * Sets the sustain level.
+ * @param sustain The sustain level in linear volume.
+ */
+ void setSustain(float sustain);
+
+ /**
+ * Returns the release time.
+ * @return The release time in seconds.
+ */
+ float getRelease() const;
+
+ /**
+ * Sets the release time.
+ * @param release The release time in seconds.
+ */
+ void setRelease(float release);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ADSRReader.h b/extern/audaspace/include/fx/ADSRReader.h
new file mode 100644
index 00000000000..a9ec076a1c5
--- /dev/null
+++ b/extern/audaspace/include/fx/ADSRReader.h
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ADSRReader.h
+ * @ingroup fx
+ * The ADSRReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is an ADSR filters.
+ */
+class AUD_API ADSRReader : public EffectReader
+{
+private:
+ enum ADSRState
+ {
+ ADSR_STATE_INVALID = 0, /// Invalid ADSR state or finished.
+ ADSR_STATE_ATTACK = 1, /// Initial attack state.
+ ADSR_STATE_DECAY = 2, /// Decay state.
+ ADSR_STATE_SUSTAIN = 3, /// Sustain state.
+ ADSR_STATE_RELEASE = 4 /// Release state.
+ };
+
+ /**
+ * Attack time.
+ */
+ float m_attack;
+
+ /**
+ * Decay time.
+ */
+ float m_decay;
+
+ /**
+ * Sustain level.
+ */
+ float m_sustain;
+
+ /**
+ * Release time.
+ */
+ float m_release;
+
+ /**
+ * Current state.
+ */
+ ADSRState m_state;
+
+ /**
+ * Current level.
+ */
+ float m_level;
+
+ // delete copy constructor and operator=
+ ADSRReader(const ADSRReader&) = delete;
+ ADSRReader& operator=(const ADSRReader&) = delete;
+
+ void AUD_LOCAL nextState(ADSRState state);
+
+public:
+ /**
+ * Creates a new ADSR reader.
+ * \param reader The reader to read from.
+ * \param attack The attack time in seconds.
+ * \param decay The decay time in seconds.
+ * \param sustain The sustain level, should be in range [0 - 1].
+ * \param release The release time in seconds.
+ */
+ ADSRReader(std::shared_ptr<IReader> reader, float attack, float decay, float sustain, float release);
+
+ virtual ~ADSRReader();
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+ /**
+ * Triggers the release.
+ */
+ void release();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Accumulator.h b/extern/audaspace/include/fx/Accumulator.h
new file mode 100644
index 00000000000..d0c635d663c
--- /dev/null
+++ b/extern/audaspace/include/fx/Accumulator.h
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Accumulator.h
+ * @ingroup fx
+ * The Accumulator class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * This sound creates an accumulator reader.
+ *
+ * The accumulator adds the difference at the input to the last output in case
+ * it's positive. In additive mode it additionaly adds the difference always.
+ * So in case the difference is positive, it's added twice.
+ */
+class AUD_API Accumulator : public Effect
+{
+private:
+ /**
+ * Whether the accumulator is additive.
+ */
+ const bool m_additive;
+
+ // delete copy constructor and operator=
+ Accumulator(const Accumulator&) = delete;
+ Accumulator& operator=(const Accumulator&) = delete;
+
+public:
+ /**
+ * Creates a new accumulator sound.
+ * \param sound The input sound.
+ * \param additive Whether the accumulator is additive.
+ */
+ Accumulator(std::shared_ptr<ISound> sound, bool additive = false);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The accumulatorFilterAdditive function implements the doFilterIIR callback
+ * for the additive accumulator filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param useless A user defined pointer that is not needed for this filter.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL accumulatorFilterAdditive(CallbackIIRFilterReader* reader, void* useless);
+
+ /**
+ * The accumulatorFilter function implements the doFilterIIR callback
+ * for the non-additive accumulator filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param useless A user defined pointer that is not needed for this filter.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL accumulatorFilter(CallbackIIRFilterReader* reader, void* useless);
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/extern/audaspace/include/fx/BaseIIRFilterReader.h
index fe0a8efce64..193b98578de 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
+++ b/extern/audaspace/include/fx/BaseIIRFilterReader.h
@@ -1,48 +1,41 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/FX/AUD_BaseIIRFilterReader.h
- * \ingroup audfx
- */
+#pragma once
+/**
+ * @file BaseIIRFilterReader.h
+ * @ingroup fx
+ * The BaseIIRFilterReader class.
+ */
-#ifndef __AUD_BASEIIRFILTERREADER_H__
-#define __AUD_BASEIIRFILTERREADER_H__
+#include "fx/EffectReader.h"
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
+AUD_NAMESPACE_BEGIN
/**
* This class is a base class for infinite impulse response filters.
*/
-class AUD_BaseIIRFilterReader : public AUD_EffectReader
+class AUD_API BaseIIRFilterReader : public EffectReader
{
private:
/**
* Specs.
*/
- AUD_Specs m_specs;
+ Specs m_specs;
/**
* Length of input samples needed.
@@ -79,9 +72,9 @@ private:
*/
int m_channel;
- // hide copy constructor and operator=
- AUD_BaseIIRFilterReader(const AUD_BaseIIRFilterReader&);
- AUD_BaseIIRFilterReader& operator=(const AUD_BaseIIRFilterReader&);
+ // delete copy constructor and operator=
+ BaseIIRFilterReader(const BaseIIRFilterReader&) = delete;
+ BaseIIRFilterReader& operator=(const BaseIIRFilterReader&) = delete;
protected:
/**
@@ -90,8 +83,13 @@ protected:
* \param in The count of past input samples needed.
* \param out The count of past output samples needed.
*/
- AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out);
+ BaseIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out);
+ /**
+ * Sets the length for the required input and output samples of the IIR filter.
+ * @param in The amount of past input samples needed, including the current one.
+ * @param out The amount of past output samples needed.
+ */
void setLengths(int in, int out);
public:
@@ -115,7 +113,7 @@ public:
return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_specs.channels + m_channel];
}
- virtual ~AUD_BaseIIRFilterReader();
+ virtual ~BaseIIRFilterReader();
virtual void read(int& length, bool& eos, sample_t* buffer);
@@ -129,7 +127,7 @@ public:
* Notifies the filter about a sample rate change.
* \param rate The new sample rate.
*/
- virtual void sampleRateChanged(AUD_SampleRate rate);
+ virtual void sampleRateChanged(SampleRate rate);
};
-#endif //__AUD_BASEIIRFILTERREADER_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/BinauralReader.h b/extern/audaspace/include/fx/BinauralReader.h
new file mode 100644
index 00000000000..f5667a093f6
--- /dev/null
+++ b/extern/audaspace/include/fx/BinauralReader.h
@@ -0,0 +1,223 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file BinauralReader.h
+* @ingroup fx
+* The BinauralReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "Convolver.h"
+#include "HRTF.h"
+#include "Source.h"
+#include "util/FFTPlan.h"
+#include "util/ThreadPool.h"
+
+#include <memory>
+#include <vector>
+#include <future>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can sound different depending on its realtive position with the listener.
+*/
+class AUD_API BinauralReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The reader of the input sound.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * The HRTF set.
+ */
+ std::shared_ptr<HRTF> m_hrtfs;
+
+ /**
+ * A Source object that will be used to change the source position of the sound.
+ */
+ std::shared_ptr<Source> m_source;
+
+ /**
+ * The intended azimuth.
+ */
+ float m_Azimuth;
+
+ /**
+ * The intended elevation.
+ */
+ float m_Elevation;
+
+ /**
+ * The real azimuth being used.
+ */
+ float m_RealAzimuth;
+
+ /**
+ * The real elevation being used.
+ */
+ float m_RealElevation;
+
+ /**
+ * The FFT size, given by the FFTPlan.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response fragments, m_N/2 will be used.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices, m_N/2 will be used.
+ */
+ int m_L;
+
+ /**
+ * The array of convolvers that will be used, one per channel.
+ */
+ std::vector<std::unique_ptr<Convolver>> m_convolvers;
+
+ /**
+ * True if a transition is happening.
+ */
+ bool m_transition;
+
+ /**
+ * The position of the current transition (decreasing)
+ */
+ int m_transPos;
+
+ /**
+ * The output buffer in which the convolved data will be written and from which the reader will read.
+ */
+ sample_t* m_outBuffer;
+
+ /**
+ * The input buffer that will hold the data to be convolved.
+ */
+ sample_t* m_inBuffer;
+
+ /**
+ * Current position in which the m_outBuffer is being read.
+ */
+ int m_outBufferPos;
+
+ /**
+ * Length of rhe m_outBuffer.
+ */
+ int m_outBufLen;
+
+ /**
+ * Effective length of rhe m_outBuffer.
+ */
+ int m_eOutBufLen;
+
+ /**
+ * Flag indicating whether the end of the sound has been reached or not.
+ */
+ bool m_eosReader;
+
+ /**
+ * Flag indicating whether the end of the extra data generated in the convolution has been reached or not.
+ */
+ bool m_eosTail;
+
+ /**
+ * A vector of buffers (one per channel) on which the audio signal will be separated per channel so it can be convolved.
+ */
+ std::vector<sample_t*> m_vecOut;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * Length of the input data to be used by the channel threads.
+ */
+ int m_lastLengthIn;
+
+ /**
+ * A vector of futures to sync tasks.
+ */
+ std::vector<std::future<int>> m_futures;
+
+ // delete copy constructor and operator=
+ BinauralReader(const BinauralReader&) = delete;
+ BinauralReader& operator=(const BinauralReader&) = delete;
+
+public:
+ /**
+ * Creates a new convolver reader.
+ * \param reader A reader of the input sound to be assigned to this reader. It must have one channel.
+ * \param hrtfs A shared pointer to an HRTF object that will be used to get a particular impulse response depending on the source.
+ * \param source A shared pointer to a Source object that will be used to change the source position of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to and FFT plan that will be used for convolution.
+ * \exception Exception thrown if the specs of the HRTFs and the sound don't match or if the provided HRTF object is empty.
+ */
+ BinauralReader(std::shared_ptr<IReader> reader, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+ virtual ~BinauralReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+private:
+ /**
+ * Joins several buffers (one per channel) into the m_outBuffer.
+ * \param start The starting position from which the m_outBuffer will be written.
+ * \param len The amout of samples that will be joined.
+ * \param nConvolvers The number of convolvers that have been used. Only use 2 or 4 as possible values.
+ If the value is 4 the result will be interpolated.
+ */
+ void joinByChannel(int start, int len, int nConvolvers);
+
+ /**
+ * Loads the m_outBuffer with data.
+ * \param nConvolvers The number of convolver objects that will be used. Only 2 or 4 should be used.
+ */
+ void loadBuffer(int nConvolvers);
+
+ /**
+ * The function that the threads will run. It will process a subset of channels.
+ * \param id An id number that will determine which subset of channels will be processed.
+ * \param input A flag that will indicate if thare is input data.
+ * -If true there is new input data.
+ * -If false there isn't new input data.
+ * \return The number of samples obtained.
+ */
+ int threadFunction(int id, bool input);
+
+ bool checkSource();
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/BinauralSound.h b/extern/audaspace/include/fx/BinauralSound.h
new file mode 100644
index 00000000000..733e111dc2b
--- /dev/null
+++ b/extern/audaspace/include/fx/BinauralSound.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file BinauralSound.h
+* @ingroup fx
+* The BinauralSound class.
+*/
+
+#include "ISound.h"
+#include "HRTF.h"
+#include "Source.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a sound that can sound different depending on its realtive position with the listener.
+*/
+class AUD_API BinauralSound : public ISound
+{
+private:
+ /**
+ * A pointer to the imput sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to an HRTF object with a collection of impulse responses.
+ */
+ std::shared_ptr<HRTF> m_hrtfs;
+
+ /**
+ * A pointer to a Source object which represents the source of the sound.
+ */
+ std::shared_ptr<Source> m_source;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A shared ponter to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ // delete copy constructor and operator=
+ BinauralSound(const BinauralSound&) = delete;
+ BinauralSound& operator=(const BinauralSound&) = delete;
+
+public:
+ /**
+ * Creates a new ConvolverSound.
+ * \param sound The sound that will be convolved. It must have only one channel.
+ * \param hrtfs The HRTF set that will be used.
+ * \param source A shared pointer to a Source object that contains the source of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFTPlan object that will be used for convolution.
+ * \warning The same FFTPlan object must be used to construct both this and the HRTF object provided.
+ */
+ BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new BinauralSound. A default FFT plan will be created.
+ * \param sound The sound that will be convolved. Must have only one channel.
+ * \param hrtfs The HRTF set that will be used.
+ * \param source A shared pointer to a Source object that contains the source of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \warning To use this constructor no FFTPlan object must have been provided to the hrtfs.
+ */
+ BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the HRTF set being used.
+ * \return A shared pointer to the current HRTF object being used.
+ */
+ std::shared_ptr<HRTF> getHRTFs();
+
+ /**
+ * Changes the set of HRTFs used for convolution, it'll only affect newly created readers.
+ * \param hrtfs A shared pointer to the new HRTF object.
+ */
+ void setHRTFs(std::shared_ptr<HRTF> hrtfs);
+
+ /**
+ * Retrieves the Source object being used.
+ * \return A shared pointer to the current Source object being used.
+ */
+ std::shared_ptr<Source> getSource();
+
+ /**
+ * Changes the Source object used to change the source position of the sound.
+ * \param source A shared pointer to the new Source object.
+ */
+ void setSource(std::shared_ptr<Source> source);
+};
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Butterworth.h b/extern/audaspace/include/fx/Butterworth.h
new file mode 100644
index 00000000000..db2ad743863
--- /dev/null
+++ b/extern/audaspace/include/fx/Butterworth.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Butterworth.h
+ * @ingroup fx
+ * The Butterworth class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a butterworth lowpass filter reader.
+ */
+class AUD_API Butterworth : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Butterworth(const Butterworth&) = delete;
+ Butterworth& operator=(const Butterworth&) = delete;
+
+public:
+ /**
+ * Creates a new butterworth sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ */
+ Butterworth(std::shared_ptr<ISound> sound, float frequency);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ButterworthCalculator.h b/extern/audaspace/include/fx/ButterworthCalculator.h
new file mode 100644
index 00000000000..f4d4894c8b8
--- /dev/null
+++ b/extern/audaspace/include/fx/ButterworthCalculator.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ButterworthCalculator.h
+ * @ingroup fx
+ * The ButterworthCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The ButterworthCalculator class calculates fourth order Butterworth low pass
+ * filter coefficients for a dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL ButterworthCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ const float m_frequency;
+
+ // delete copy constructor and operator=
+ ButterworthCalculator(const ButterworthCalculator&) = delete;
+ ButterworthCalculator& operator=(const ButterworthCalculator&) = delete;
+
+public:
+ /**
+ * Creates a ButterworthCalculator object.
+ * @param frequency The cutoff frequency.
+ */
+ ButterworthCalculator(float frequency);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/CallbackIIRFilterReader.h b/extern/audaspace/include/fx/CallbackIIRFilterReader.h
new file mode 100644
index 00000000000..f1dfab70d7f
--- /dev/null
+++ b/extern/audaspace/include/fx/CallbackIIRFilterReader.h
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file CallbackIIRFilterReader.h
+ * @ingroup fx
+ * The CallbackIIRFilterReader class.
+ */
+
+#include "fx/BaseIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * The doFilterIIR callback is executed when a new sample of a callback filter
+ * should be calculated. For sample access the CallbackIIRFilterReader is
+ * provided. Furthermore a user defined pointer is also handed to the callback.
+ */
+typedef sample_t (*doFilterIIR)(CallbackIIRFilterReader*, void*);
+
+/**
+ * The endFilterIIR callback is called when the callback filter is not needed
+ * anymore. The goal of this function should be to clean up the data behind the
+ * user supplied pointer which is handed to the callback.
+ */
+typedef void (*endFilterIIR)(void*);
+
+/**
+ * This class provides an interface for infinite impulse response filters via a
+ * callback filter function.
+ */
+class AUD_API CallbackIIRFilterReader : public BaseIIRFilterReader
+{
+private:
+ /**
+ * Filter function.
+ */
+ const doFilterIIR m_filter;
+
+ /**
+ * End filter function.
+ */
+ const endFilterIIR m_endFilter;
+
+ /**
+ * Data pointer.
+ */
+ void* m_data;
+
+ // delete copy constructor and operator=
+ CallbackIIRFilterReader(const CallbackIIRFilterReader&) = delete;
+ CallbackIIRFilterReader& operator=(const CallbackIIRFilterReader&) = delete;
+
+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.
+ */
+ CallbackIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out, doFilterIIR doFilter, endFilterIIR endFilter = 0, void* data = nullptr);
+
+ virtual ~CallbackIIRFilterReader();
+
+ virtual sample_t filter();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Convolver.h b/extern/audaspace/include/fx/Convolver.h
new file mode 100644
index 00000000000..5ce134839f6
--- /dev/null
+++ b/extern/audaspace/include/fx/Convolver.h
@@ -0,0 +1,177 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Convolver.h
+* @ingroup fx
+* The Convolver class.
+*/
+
+#include "FFTConvolver.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+#include <mutex>
+#include <future>
+#include <atomic>
+#include <deque>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This class allows to convolve a sound with a very large impulse response.
+*/
+class AUD_API Convolver
+{
+private:
+ /**
+ * The FFT size, must be at least M+L-1.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response parts.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices.
+ */
+ int m_L;
+
+ /**
+ * The impulse response divided in parts.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> m_irBuffers;
+
+ /**
+ * Accumulation buffers for the threads.
+ */
+ std::vector<fftwf_complex*> m_threadAccBuffers;
+
+ /**
+ * A vector of FFTConvolvers used to calculate the partial convolutions.
+ */
+ std::vector<std::unique_ptr<FFTConvolver>> m_fftConvolvers;
+
+ /**
+ * The actual number of threads being used.
+ */
+ int m_numThreads;
+
+ /**
+ * A pool of threads that will be used for convolution.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A vector of futures used for thread sync
+ */
+ std::vector<std::future<bool>> m_futures;
+
+ /**
+ * A mutex for the sum of thread accumulators.
+ */
+ std::mutex m_sumMutex;
+
+ /**
+ * A flag to control thread execution when a reset is scheduled.
+ */
+ std::atomic_bool m_resetFlag;
+
+ /**
+ * Global accumulation buffer.
+ */
+ fftwf_complex* m_accBuffer;
+
+ /**
+ * Delay line.
+ */
+ std::deque<fftwf_complex*> m_delayLine;
+
+ /**
+ * The complete length of the impulse response.
+ */
+ int m_irLength;
+
+ /**
+ * Counter for the tail;
+ */
+ int m_tailCounter;
+
+ /**
+ * Flag end of sound;
+ */
+ bool m_eos;
+
+ // delete copy constructor and operator=
+ Convolver(const Convolver&) = delete;
+ Convolver& operator=(const Convolver&) = delete;
+
+public:
+
+ /**
+ * Creates a new FFTConvolver.
+ * \param ir A shared pointer to a vector with the data of the various impulse response parts in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ * \param irLength The length of the full impulse response.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFT plan that will be used for convolution.
+ */
+ Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ virtual ~Convolver();
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * Given a plan of size N, the amount of samples convolved by one call to this method will be N/2.
+ * \param[in] inBuffer A buffer with the input data to be convolved, nullptr if the source sound has ended (the convolved sound is larger than the source sound).
+ * \param[in] outBuffer A buffer in which the convolved data will be written. Its size must be at least N/2.
+ * \param[in,out] length The number of samples you wish to obtain. If an inBuffer is provided this argument must match its length.
+ * When this method returns, the value of length represents the number of samples written into the outBuffer.
+ * \param[out] eos True if the end of the sound is reached, false otherwise.
+ */
+ void getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos);
+
+ /**
+ * Resets all the internally stored data so the convolution of a new sound can be started.
+ */
+ void reset();
+
+ /**
+ * Retrieves the current impulse response being used.
+ * \return The current impulse response.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> getImpulseResponse();
+
+ /**
+ * Changes the impulse response and resets the convolver.
+ * \param ir A shared pointer to a vector with the data of the various impulse response parts in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ */
+ void setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir);
+
+private:
+
+ /**
+ * This function will be enqueued into the thread pool, and will process the input signal with a subset of the impulse response parts.
+ * \param id The id of the thread, starting with 0.
+ */
+ bool threadFunction(int id);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ConvolverReader.h b/extern/audaspace/include/fx/ConvolverReader.h
new file mode 100644
index 00000000000..2ce917daec5
--- /dev/null
+++ b/extern/audaspace/include/fx/ConvolverReader.h
@@ -0,0 +1,198 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ConvolverReader.h
+* @ingroup fx
+* The ConvolverReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "Convolver.h"
+#include "ImpulseResponse.h"
+#include "util/FFTPlan.h"
+#include "util/ThreadPool.h"
+
+#include <memory>
+#include <vector>
+#include <future>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can be modified depending on a given impulse response.
+*/
+class AUD_API ConvolverReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The reader of the input sound.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * The impulse response in the frequency domain.
+ */
+ std::shared_ptr<ImpulseResponse> m_ir;
+
+ /**
+ * The FFT size, given by the FFTPlan.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response fragments, m_N/2 will be used.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices, m_N/2 will be used.
+ */
+ int m_L;
+
+ /**
+ * The array of convolvers that will be used, one per channel.
+ */
+ std::vector<std::unique_ptr<Convolver>> m_convolvers;
+
+ /**
+ * The output buffer in which the convolved data will be written and from which the reader will read.
+ */
+ sample_t* m_outBuffer;
+
+ /**
+ * A vector of buffers (one per channel) on which the audio signal will be separated per channel so it can be convolved.
+ */
+ std::vector<sample_t*> m_vecInOut;
+
+ /**
+ * Current position in which the m_outBuffer is being read.
+ */
+ int m_outBufferPos;
+
+ /**
+ * Effective length of the m_outBuffer.
+ */
+ int m_eOutBufLen;
+
+ /**
+ * Real length of the m_outBuffer.
+ */
+ int m_outBufLen;
+
+ /**
+ * Flag indicating whether the end of the sound has been reached or not.
+ */
+ bool m_eosReader;
+
+ /**
+ * Flag indicating whether the end of the extra data generated in the convolution has been reached or not.
+ */
+ bool m_eosTail;
+
+ /**
+ * The number of channels of the sound to be convolved.
+ */
+ int m_inChannels;
+
+ /**
+ * The number of channels of the impulse response.
+ */
+ int m_irChannels;
+
+ /**
+ * The number of threads used for channels.
+ */
+ int m_nChannelThreads;
+
+ /**
+ * Length of the input data to be used by the channel threads.
+ */
+ int m_lastLengthIn;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A vector of futures to sync tasks.
+ */
+ std::vector<std::future<int>> m_futures;
+
+ // delete copy constructor and operator=
+ ConvolverReader(const ConvolverReader&) = delete;
+ ConvolverReader& operator=(const ConvolverReader&) = delete;
+
+public:
+ /**
+ * Creates a new convolver reader.
+ * \param reader A reader of the input sound to be assigned to this reader.
+ * \param ir A shared pointer to an impulseResponse object that will be used to convolve the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to and FFT plan that will be used for convolution.
+ * \exception Exception thrown if impulse response doesn't match the specs (number fo channels and rate) of the input reader.
+ */
+ ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+ virtual ~ConvolverReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+private:
+ /**
+ * Divides a sound buffer in several buffers, one per channel.
+ * \param buffer The buffer that will be divided.
+ * \param len The length of the buffer.
+ */
+ void divideByChannel(const sample_t* buffer, int len);
+
+ /**
+ * Joins several buffers (one per channel) into the m_outBuffer.
+ * \param start The starting position from which the m_outBuffer will be written.
+ * \param len The amout of samples that will be joined.
+ */
+ void joinByChannel(int start, int len);
+
+ /**
+ * Loads the m_outBuffer with data.
+ */
+ void loadBuffer();
+
+ /**
+ * The function that the threads will run. It will process a subset of channels.
+ * \param id An id number that will determine which subset of channels will be processed.
+ * \param input A flag that will indicate if thare is input data.
+ * -If true there is new input data.
+ * -If false there isn't new input data.
+ * \return The number of samples obtained.
+ */
+ int threadFunction(int id, bool input);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/ConvolverSound.h b/extern/audaspace/include/fx/ConvolverSound.h
new file mode 100644
index 00000000000..957e3b8af1c
--- /dev/null
+++ b/extern/audaspace/include/fx/ConvolverSound.h
@@ -0,0 +1,100 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ConvolverSound.h
+* @ingroup fx
+* The ConvolverSound class.
+*/
+
+#include "ISound.h"
+#include "ImpulseResponse.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a sound that can be modified depending on a given impulse response.
+*/
+class AUD_API ConvolverSound : public ISound
+{
+private:
+ /**
+ * A pointer to the imput sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to the impulse response.
+ */
+ std::shared_ptr<ImpulseResponse> m_impulseResponse;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A shared ponter to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ // delete copy constructor and operator=
+ ConvolverSound(const ConvolverSound&) = delete;
+ ConvolverSound& operator=(const ConvolverSound&) = delete;
+
+public:
+ /**
+ * Creates a new ConvolverSound.
+ * \param sound The sound that will be convolved.
+ * \param impulseResponse The impulse response sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFTPlan object that will be used for convolution.
+ * \warning The same FFTPlan object must be used to construct both this and the ImpulseResponse object provided.
+ */
+ ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new ConvolverSound. A default FFT plan will be created.
+ * \param sound The sound that will be convolved.
+ * \param impulseResponse The impulse response sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \warning To use this constructor no FFTPlan object must have been provided to the inpulseResponse.
+ */
+ ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the impulse response sound being used.
+ * \return A shared pointer to the current impulse response being used.
+ */
+ std::shared_ptr<ImpulseResponse> getImpulseResponse();
+
+ /**
+ * Changes the inpulse response used for convolution, it'll only affect newly created readers.
+ * \param impulseResponse A shared pointer to the new impulse response sound.
+ */
+ void setImpulseResponse(std::shared_ptr<ImpulseResponse> impulseResponse);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Delay.h b/extern/audaspace/include/fx/Delay.h
new file mode 100644
index 00000000000..d6ab93ca351
--- /dev/null
+++ b/extern/audaspace/include/fx/Delay.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Delay.h
+ * @ingroup fx
+ * The Delay class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays another sound delayed.
+ */
+class AUD_API Delay : public Effect
+{
+private:
+ /**
+ * The delay in samples.
+ */
+ const float m_delay;
+
+ // delete copy constructor and operator=
+ Delay(const Delay&) = delete;
+ Delay& operator=(const Delay&) = delete;
+
+public:
+ /**
+ * Creates a new delay sound.
+ * \param sound The input sound.
+ * \param delay The desired delay in seconds.
+ */
+ Delay(std::shared_ptr<ISound> sound, float delay = 0);
+
+ /**
+ * Returns the delay in seconds.
+ */
+ float getDelay() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DelayReader.h b/extern/audaspace/include/fx/DelayReader.h
new file mode 100644
index 00000000000..fe37e56d83e
--- /dev/null
+++ b/extern/audaspace/include/fx/DelayReader.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DelayReader.h
+ * @ingroup fx
+ * The DelayReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and delays it.
+ */
+class AUD_API DelayReader : public EffectReader
+{
+private:
+ /**
+ * The delay level.
+ */
+ const int m_delay;
+
+ /**
+ * The remaining delay for playback.
+ */
+ int m_remdelay;
+
+ // delete copy constructor and operator=
+ DelayReader(const DelayReader&) = delete;
+ DelayReader& operator=(const DelayReader&) = delete;
+
+public:
+ /**
+ * Creates a new delay reader.
+ * \param reader The reader to read from.
+ * \param delay The delay in seconds.
+ */
+ DelayReader(std::shared_ptr<IReader> reader, float delay);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicIIRFilter.h b/extern/audaspace/include/fx/DynamicIIRFilter.h
new file mode 100644
index 00000000000..5528e7c7b9b
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicIIRFilter.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DynamicIIRFilter.h
+ * @ingroup fx
+ * The DynamicIIRFilter class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IDynamicIIRFilterCalculator;
+
+/**
+ * This sound creates a IIR filter reader.
+ *
+ * This means that on sample rate change the filter recalculates its
+ * coefficients.
+ */
+class AUD_API DynamicIIRFilter : public Effect
+{
+protected:
+ /// The IDynamicIIRFilterCalculator that calculates the dynamic filter coefficients.
+ std::shared_ptr<IDynamicIIRFilterCalculator> m_calculator;
+
+public:
+ /**
+ * Creates a new Dynmic IIR filter sound.
+ * \param sound The input sound.
+ * \param calculator The calculator which recalculates the dynamic filter coefficients.
+ */
+ DynamicIIRFilter(std::shared_ptr<ISound> sound, std::shared_ptr<IDynamicIIRFilterCalculator> calculator);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicIIRFilterReader.h b/extern/audaspace/include/fx/DynamicIIRFilterReader.h
new file mode 100644
index 00000000000..9e2267243ce
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicIIRFilterReader.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DynamicIIRFilterReader.h
+ * @ingroup fx
+ * The DynamicIIRFilterReader class.
+ */
+
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IDynamicIIRFilterCalculator;
+
+/**
+ * This class is for dynamic infinite impulse response filters with simple
+ * coefficients that change depending on the sample rate.
+ */
+class AUD_API DynamicIIRFilterReader : public IIRFilterReader
+{
+private:
+ /**
+ * The sound for dynamically recalculating filter coefficients.
+ */
+ std::shared_ptr<IDynamicIIRFilterCalculator> m_calculator;
+
+public:
+ /**
+ * Creates a new DynamicIIRFilterReader.
+ * @param reader The reader the filter is applied on.
+ * @param calculator The IDynamicIIRFilterCalculator that recalculates the filter coefficients.
+ */
+ DynamicIIRFilterReader(std::shared_ptr<IReader> reader,
+ std::shared_ptr<IDynamicIIRFilterCalculator> calculator);
+
+ /**
+ * The function sampleRateChanged is called whenever the sample rate of the
+ * underlying reader changes and thus updates the filter coefficients.
+ * @param rate The new sample rate.
+ */
+ virtual void sampleRateChanged(SampleRate rate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicMusic.h b/extern/audaspace/include/fx/DynamicMusic.h
new file mode 100644
index 00000000000..5d59f77401a
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicMusic.h
@@ -0,0 +1,235 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file DynamicMusic.h
+* @ingroup fx
+* The DynamicMusic class.
+*/
+
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "ISound.h"
+
+#include <memory>
+#include <vector>
+#include <thread>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to play music depending on a current "scene", scene changes are managed by the class.
+* The default scene is silent and has id 0.
+*/
+class AUD_API DynamicMusic
+{
+private:
+ /**
+ * Matrix of pointers which will store the sounds of the scenes and the transitions between them.
+ */
+ std::vector<std::vector<std::shared_ptr<ISound>>> m_scenes;
+
+ /**
+ * Id of the current scene.
+ */
+ std::atomic_int m_id;
+
+ /**
+ * Length of the crossfade transition in seconds, used when no custom transition has been set.
+ */
+ float m_fadeTime;
+
+ /**
+ * Handle to the playback of the current scene.
+ */
+ std::shared_ptr<IHandle> m_currentHandle;
+
+ /**
+ * Handle used during transitions.
+ */
+ std::shared_ptr<IHandle> m_transitionHandle;
+
+ /**
+ * Device used for playback.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * Flag that is true when a transition is happening.
+ */
+ std::atomic_bool m_transitioning;
+
+ /**
+ * Flag that is true when the music is paused.
+ */
+ std::atomic_bool m_stopThread;
+
+ /**
+ * Id of the sound that will play with the next transition.
+ */
+ std::atomic_int m_soundTarget;
+
+ /**
+ * Volume of the scenes.
+ */
+ float m_volume;
+
+ /**
+ * A thread that manages the crossfade transition.
+ */
+ std::thread m_fadeThread;
+
+ // delete copy constructor and operator=
+ DynamicMusic(const DynamicMusic&) = delete;
+ DynamicMusic& operator=(const DynamicMusic&) = delete;
+
+public:
+ /**
+ * Creates a new dynamic music manager with the default silent scene (id: 0).
+ * \param device The device that will be used to play sounds.
+ */
+ DynamicMusic(std::shared_ptr<IDevice> device);
+
+ virtual ~DynamicMusic();
+
+ /**
+ * Adds a new scene to the manager.
+ * \param sound The sound that will play when the scene is selected with the changeScene().
+ * \return The identifier of the new scene.
+ */
+ int addScene(std::shared_ptr<ISound> sound);
+
+ /**
+ * Changes to another scene.
+ * \param id The id of the scene which should start playing the changeScene method.
+ * \return
+ * - true if the change has been scheduled succesfully.
+ * - false if there already is a transition in course or the scene selected doesnt exist.
+ */
+ bool changeScene(int id);
+
+ /**
+ * Retrieves the scene currently selected.
+ * \return The identifier of the current scene.
+ */
+ int getScene();
+
+ /**
+ * Adds a new transition between scenes
+ * \param init The id of the initial scene that will allow the transition to play.
+ * \param end The id if the target scene for the transition.
+ * \param sound The sound that will play when the scene changes from init to end.
+ * \return false if the init or end scenes don't exist.
+ */
+ bool addTransition(int init, int end, std::shared_ptr<ISound> sound);
+
+ /**
+ * Sets the length of the crossfade transition (default 1 second).
+ * \param seconds The time in seconds.
+ */
+ void setFadeTime(float seconds);
+
+ /**
+ * Gets the length of the crossfade transition (default 1 second).
+ * \return The length of the cressfade transition in seconds.
+ */
+ float getFadeTime();
+
+ /**
+ * Resumes a paused sound.
+ * \return
+ * - true if the sound has been resumed.
+ * - false if the sound isn't paused or the handle is invalid.
+ */
+ bool resume();
+
+ /**
+ * Pauses the current played back sound.
+ * \return
+ * - true if the sound has been paused.
+ * - false if the sound isn't playing back or the handle is invalid.
+ */
+ bool pause();
+
+ /**
+ * Seeks in the current played back sound.
+ * \param position The new position from where to play back, in seconds.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ * \warning Whether the seek works or not depends on the sound source.
+ */
+ bool seek(float position);
+
+ /**
+ * Retrieves the current playback position of a sound.
+ * \return The playback position in seconds, or 0.0 if the handle is
+ * invalid.
+ */
+ float getPosition();
+
+ /**
+ * Retrieves the volume of the scenes.
+ * \return The volume.
+ */
+ float getVolume();
+
+ /**
+ * Sets the volume for the scenes.
+ * \param volume The volume.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ bool setVolume(float volume);
+
+ /**
+ * Returns the status of the current played back sound.
+ * \return
+ * - STATUS_INVALID if the sound has stopped or the handle is
+ *. invalid
+ * - STATUS_PLAYING if the sound is currently played back.
+ * - STATUS_PAUSED if the sound is currently paused.
+ * - STATUS_STOPPED if the sound finished playing and is still
+ * kept in the device.
+ * \see Status
+ */
+ Status getStatus();
+
+ /**
+ * Stops any played back or paused sound and sets the dynamic music player to default silent state (scene 0)
+ * \return
+ * - true if the sound has been stopped.
+ * - false if the handle is invalid.
+ */
+ bool stop();
+
+ private:
+ //Callbacks used to schedule transitions after a sound ends.
+ static void transitionCallback(void* player);
+ static void sceneCallback(void* player);
+ //These functions can fade sounds in and out if used with a thread.
+ void crossfadeThread();
+ void fadeInThread();
+ void fadeOutThread();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Effect.h b/extern/audaspace/include/fx/Effect.h
new file mode 100644
index 00000000000..471e37b5ecf
--- /dev/null
+++ b/extern/audaspace/include/fx/Effect.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Effect.h
+ * @ingroup fx
+ * The Effect class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound is a base class for all effect factories that take one other
+ * sound as input.
+ */
+class AUD_API Effect : public ISound
+{
+private:
+ // delete copy constructor and operator=
+ Effect(const Effect&) = delete;
+ Effect& operator=(const Effect&) = delete;
+
+protected:
+ /**
+ * If there is no reader it is created out of this sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * Returns the reader created out of the sound.
+ * This method can be used for the createReader function of the implementing
+ * classes.
+ * \return The reader created out of the sound.
+ */
+ inline std::shared_ptr<IReader> getReader() const
+ {
+ return m_sound->createReader();
+ }
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ */
+ Effect(std::shared_ptr<ISound> sound);
+
+ /**
+ * Destroys the sound.
+ */
+ virtual ~Effect();
+
+ /**
+ * Returns the saved sound.
+ * \return The sound or nullptr if there has no sound been saved.
+ */
+ std::shared_ptr<ISound> getSound() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/EffectReader.h b/extern/audaspace/include/fx/EffectReader.h
new file mode 100644
index 00000000000..85eff6a8ab9
--- /dev/null
+++ b/extern/audaspace/include/fx/EffectReader.h
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file EffectReader.h
+ * @ingroup fx
+ * The EffectReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader is a base class for all effect readers that take one other reader
+ * as input.
+ */
+class AUD_API EffectReader : public IReader
+{
+private:
+ // delete copy constructor and operator=
+ EffectReader(const EffectReader&) = delete;
+ EffectReader& operator=(const EffectReader&) = delete;
+
+protected:
+ /**
+ * The reader to read from.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+public:
+ /**
+ * Creates a new effect reader.
+ * \param reader The reader to read from.
+ */
+ EffectReader(std::shared_ptr<IReader> reader);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~EffectReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Envelope.h b/extern/audaspace/include/fx/Envelope.h
new file mode 100644
index 00000000000..3d44e897b3a
--- /dev/null
+++ b/extern/audaspace/include/fx/Envelope.h
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Envelope.h
+ * @ingroup fx
+ * The Envelope class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+struct EnvelopeParameters;
+
+/**
+ * This sound creates an envelope follower reader.
+ */
+class AUD_API Envelope : public Effect
+{
+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;
+
+ // delete copy constructor and operator=
+ Envelope(const Envelope&) = delete;
+ Envelope& operator=(const Envelope&) = delete;
+
+public:
+ /**
+ * Creates a new envelope sound.
+ * \param sound The input sound.
+ * \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.
+ */
+ Envelope(std::shared_ptr<ISound> sound, float attack, float release,
+ float threshold, float arthreshold);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The envelopeFilter function implements the doFilterIIR callback
+ * for the callback IIR filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param param The envelope parameters.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL envelopeFilter(CallbackIIRFilterReader* reader, EnvelopeParameters* param);
+
+ /**
+ * The endEnvelopeFilter function implements the endFilterIIR callback
+ * for the callback IIR filter.
+ * @param param The envelope parameters.
+ */
+ static void AUD_LOCAL endEnvelopeFilter(EnvelopeParameters* param);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/FFTConvolver.h b/extern/audaspace/include/fx/FFTConvolver.h
new file mode 100644
index 00000000000..62ce1cbf5ad
--- /dev/null
+++ b/extern/audaspace/include/fx/FFTConvolver.h
@@ -0,0 +1,196 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file FFTConvolver.h
+* @ingroup fx
+* The FFTConvolver class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This class allows to easily convolve a sound using the Fourier transform.
+*/
+class AUD_API FFTConvolver
+{
+private:
+ /**
+ * A shared pointer to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ /**
+ * The FFT size, must be at least M+L-1.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices.
+ */
+ int m_L;
+
+ /**
+ * The real length of the internal buffer in fftwf_complex elements.
+ */
+ int m_realBufLen;
+
+ /**
+ * The internal buffer for the FFTS.
+ */
+ std::complex<sample_t>* m_inBuffer;
+
+ /**
+ * A shift buffer for the FDL method
+ */
+ sample_t* m_shiftBuffer;
+
+ /**
+ * A buffer to store the extra data obtained after each partial convolution.
+ */
+ float* m_tail;
+
+ /**
+ * The provided impulse response.
+ */
+ std::shared_ptr<std::vector<std::complex<sample_t>>> m_irBuffer;
+
+ /**
+ * If the tail is being read, this marks the current position.
+ */
+ int m_tailPos;
+
+ // delete copy constructor and operator=
+ FFTConvolver(const FFTConvolver&) = delete;
+ FFTConvolver& operator=(const FFTConvolver&) = delete;
+
+public:
+ /**
+ * Creates a new FFTConvolver.
+ * \param ir A shared pointer to a vector with the impulse response data in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ * \param plan A shared pointer to and FFT plan.
+ */
+ FFTConvolver(std::shared_ptr<std::vector<std::complex<sample_t>>> ir, std::shared_ptr<FFTPlan> plan);
+ virtual ~FFTConvolver();
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved.
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved (the length of both the inBuffer and the outBuffer).
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail, setting this variable to 0 since no data would be
+ * written in the outBuffer.
+ */
+ void getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved.
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved (the length of both the inBuffer and the outBuffer).
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail, setting this variable to 0 since no data would be
+ * written in the outBuffer.
+ * \param[in] transformedData A pointer to a buffer in which the Fourier transform of the input will be written.
+ */
+ void getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length, fftwf_complex* transformedData);
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved. Its length must be N/2 + 1
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved and the length of the outBuffer.
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail and set the value of length to 0 since no data would be
+ * written in the outBuffer.
+ */
+ void getNext(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Gets the internally stored extra data which is result of the convolution.
+ * \param[in,out] length The count of samples that should be read. Shall
+ * contain the real count of samples after reading, in case
+ * there were only fewer samples available.
+ * A smaller value also indicates the end of the data.
+ * \param[out] eos End of stream, whether the end is reached or not.
+ * \param[in] buffer The pointer to the buffer to read into.
+ */
+ void getTail(int& length, bool& eos, sample_t* buffer);
+
+ /**
+ * Resets the internally stored data so a new convolution can be started.
+ */
+ void clear();
+
+ /**
+ * Calculates the Inverse Fast Fourier Transform of the input array.
+ * \param[in] inBuffer A buffer with the input data to be transformed. Its length must be N/2 + 1
+ * \param[in] outBuffer A pointer to the buffer in which the transform result will be written.
+ * \param[in,out] length The number of samples to be transformed and the length of the outBuffer.
+ * It must be equal or lower than N, but tipically N/2 should be used (N=size of the FFTPlan) or the call will fail and the value
+ * of length will be setted to 0, since no data would be written in the outBuffer.
+ */
+ void IFFT_FDL(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Multiplicates a frequency domain input by the impulse response and accumulates the result to a buffer.
+ * \param[in] inBuffer A buffer of complex numbers, samples in the frequency domain, that will be multiplied by the impulse response. Its length must be N/2 + 1
+ * \param[in] accBuffer A pointer to the buffer into which the result of the multiplication will be summed. Its length must be N/2 + 1
+ */
+ void getNextFDL(const std::complex<sample_t>* inBuffer, std::complex<sample_t>* accBuffer);
+
+ /**
+ * Transforms an input array of real data to the frequency domain and multiplies it by the impulse response. The result is accumulated to a buffer.
+ * \param[in] inBuffer A buffer of real numbers, samples in the time domain, that will be multiplied by the impulse response.
+ * \param[in] accBuffer A pointer to the buffer into which the result of the multiplication will be summed. Its length must be N/2 + 1.
+ * \param[in,out] length The number of samples to be transformed and the length of the inBuffer.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail and the value
+ * of length will be setted to 0, since no data would be written in the outBuffer.
+ * \param[in] transformedData A pointer to a buffer in which the Fourier transform of the input will be written.
+ */
+ void getNextFDL(const sample_t* inBuffer, std::complex<sample_t>* accBuffer, int& length, fftwf_complex* transformedData);
+
+ /**
+ * Changes the impulse response and resets the FFTConvolver.
+ * \param ir A shared pointer to a vector with the data of the impulse response in the frequency domain.
+ */
+ void setImpulseResponse(std::shared_ptr<std::vector<std::complex<sample_t>>> ir);
+
+ /**
+ * Retrieves the current impulse response being used.
+ * \return The current impulse response.
+ */
+ std::shared_ptr<std::vector<std::complex<sample_t>>> getImpulseResponse();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Fader.h b/extern/audaspace/include/fx/Fader.h
new file mode 100644
index 00000000000..63280aec292
--- /dev/null
+++ b/extern/audaspace/include/fx/Fader.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Fader.h
+ * @ingroup fx
+ * The Fader class.
+ */
+
+#include "fx/Effect.h"
+#include "fx/FaderReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound fades another sound.
+ * If the fading type is FADE_IN, everything before the fading start will be
+ * silenced, for FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_API Fader : public Effect
+{
+private:
+ /**
+ * The fading type.
+ */
+ const FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ const float m_start;
+
+ /**
+ * The fading length.
+ */
+ const float m_length;
+
+ // delete copy constructor and operator=
+ Fader(const Fader&) = delete;
+ Fader& operator=(const Fader&) = delete;
+
+public:
+ /**
+ * Creates a new fader sound.
+ * \param sound The input sound.
+ * \param type The fading type.
+ * \param start The time where fading should start in seconds.
+ * \param length How long fading should last in seconds.
+ */
+ Fader(std::shared_ptr<ISound> sound,
+ FadeType type = FADE_IN,
+ float start = 0.0f, float length = 1.0f);
+
+ /**
+ * Returns the fading type.
+ */
+ FadeType getType() const;
+
+ /**
+ * Returns the fading start.
+ */
+ float getStart() const;
+
+ /**
+ * Returns the fading length.
+ */
+ float getLength() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/FaderReader.h b/extern/audaspace/include/fx/FaderReader.h
new file mode 100644
index 00000000000..99ea3d28938
--- /dev/null
+++ b/extern/audaspace/include/fx/FaderReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FaderReader.h
+ * @ingroup fx
+ * Defines the FaderReader class as well as the two fading types.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/// Fading types.
+enum FadeType
+{
+ FADE_IN,
+ FADE_OUT
+};
+
+/**
+ * This class fades another reader.
+ * If the fading type is FADE_IN, everything before the fading start will be
+ * silenced, for FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_API FaderReader : public EffectReader
+{
+private:
+ /**
+ * The fading type.
+ */
+ const FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ const float m_start;
+
+ /**
+ * The fading length.
+ */
+ const float m_length;
+
+ // delete copy constructor and operator=
+ FaderReader(const FaderReader&) = delete;
+ FaderReader& operator=(const FaderReader&) = delete;
+
+public:
+ /**
+ * Creates a new fader reader.
+ * \param reader The reader that this effect is applied on.
+ * \param type The fading type.
+ * \param start The time where fading should start in seconds.
+ * \param length How long fading should last in seconds.
+ */
+ FaderReader(std::shared_ptr<IReader> reader, FadeType type,
+ float start,float length);
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HRTF.h b/extern/audaspace/include/fx/HRTF.h
new file mode 100644
index 00000000000..750d5f18991
--- /dev/null
+++ b/extern/audaspace/include/fx/HRTF.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file HRTF.h
+* @ingroup fx
+* The HRTF class.
+*/
+
+#include "util/StreamBuffer.h"
+#include "util/FFTPlan.h"
+#include "ImpulseResponse.h"
+
+#include <memory>
+#include <vector>
+#include <unordered_map>
+#include <utility>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a complete set of HRTFs.
+*/
+class AUD_API HRTF
+{
+private:
+ /**
+ * An unordered map of unordered maps containing the ImpulseResponse objects of the HRTFs.
+ */
+ std::unordered_map<float, std::unordered_map<float, std::shared_ptr<ImpulseResponse>>> m_hrtfs;
+
+ /**
+ * The FFTPlan used to create the ImpulseResponses.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ /**
+ * The specifications of the HRTFs.
+ */
+ Specs m_specs;
+
+ /**
+ * True if the HRTF object is empty.
+ */
+ bool m_empty;
+
+ // delete copy constructor and operator=
+ HRTF(const HRTF&) = delete;
+ HRTF& operator=(const HRTF&) = delete;
+
+public:
+ /**
+ * Creates a new empty HRTF object that will instance it own FFTPlan with default size.
+ */
+ HRTF();
+
+ /**
+ * Creates a new empty HRTF object.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse responses added.
+ */
+ HRTF(std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Adds a new HRTF to the class.
+ * \param impulseResponse A shared pointer to an StreamBuffer with the HRTF.
+ * \param azimuth The azimuth angle of the HRTF. Interval [0,360).
+ * \param elevation The elevation angle of the HRTF.
+ * \return True if the impulse response was added successfully, false otherwise (the specs weren't correct).
+ */
+ bool addImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, float azimuth, float elevation);
+
+ /**
+ * Retrieves a pair of HRTFs for a certain azimuth and elevation. If no exact match is found, the closest ones will be chosen (the elevation has priority over the azimuth).
+ * \param[in,out] azimuth The desired azimuth angle. If no exact match is found, the value of azimuth will represent the actual azimuth elevation of the chosen HRTF. Interval [0,360)
+ * \param[in,out] elevation The desired elevation angle. If no exact match is found, the value of elevation will represent the actual elevation angle of the chosen HRTF.
+ * \return A pair of shared pointers to ImpulseResponse objects containing the HRTFs for the left (first element) and right (second element) ears.
+ */
+ std::pair<std::shared_ptr<ImpulseResponse>, std::shared_ptr<ImpulseResponse>> getImpulseResponse(float &azimuth, float &elevation);
+
+ /**
+ * Retrieves the specs shared by all the HRTFs.
+ * \return The shared specs of all the HRTFs.
+ */
+ Specs getSpecs();
+
+ /**
+ * Retrieves the state of the HRTF object.
+ * \return True if it is empty, false otherwise.
+ */
+ bool isEmpty();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HRTFLoader.h b/extern/audaspace/include/fx/HRTFLoader.h
new file mode 100644
index 00000000000..893184ae909
--- /dev/null
+++ b/extern/audaspace/include/fx/HRTFLoader.h
@@ -0,0 +1,99 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file HRTFLoader.h
+* @ingroup fx
+* The HRTFLoader class.
+*/
+
+#include "Audaspace.h"
+#include "fx/HRTF.h"
+#include "util/FFTPlan.h"
+
+#include <string>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This loader provides a method to load all the HRTFs in one directory, provided they follow the following naming scheme:
+* Example: L-10e210a.wav
+* The first character refers to the ear from which the HRTF was recorded: 'L' for a left ear and 'R' for a right ear.
+* Next is the elevation angle followed by the 'e' character. [-90, 90]
+* Then is the azimuth angle followed by the 'a' character. [0, 360)
+* For a sound source situated at the left of the listener the azimuth angle regarding the left ear is 90 while the angle regarding the right ear is 270.
+* KEMAR HRTFs use this naming scheme.
+*/
+class AUD_API HRTFLoader
+{
+private:
+ // delete normal constructor, copy constructor and operator=
+ HRTFLoader(const HRTFLoader&) = delete;
+ HRTFLoader& operator=(const HRTFLoader&) = delete;
+ HRTFLoader() = delete;
+
+public:
+ /**
+ * Loads all the left ear HRTFs in the directory.Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param plan The plan that will be used to create the HRTF object.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the right ear HRTFs in the directory. Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param plan The plan that will be used to create the HRTF object.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the left ear HRTFs in the directory.Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadLeftHRTFs(const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the right ear HRTFs in the directory. Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadRightHRTFs(const std::string& fileExtension, const std::string& path = "");
+
+
+private:
+
+ /**
+ * Loads all the HRTFs in the directory and subdirectories.
+ * \param hrtfs An HRTF object in which to load the HRTFs.
+ * \param ear 'L' to load left ear HRTFs, 'R' to load right ear HRTFs.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ */
+ static void loadHRTFs(std::shared_ptr<HRTF>hrtfs, char ear, const std::string& fileExtension, const std::string& path = "");
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Highpass.h b/extern/audaspace/include/fx/Highpass.h
new file mode 100644
index 00000000000..6bfb6d7885d
--- /dev/null
+++ b/extern/audaspace/include/fx/Highpass.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Highpass.h
+ * @ingroup fx
+ * The Highpass class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a highpass filter reader.
+ */
+class AUD_API Highpass : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Highpass(const Highpass&) = delete;
+ Highpass& operator=(const Highpass&) = delete;
+
+public:
+ /**
+ * Creates a new highpass sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ Highpass(std::shared_ptr<ISound> sound, float frequency, float Q = 1.0f);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HighpassCalculator.h b/extern/audaspace/include/fx/HighpassCalculator.h
new file mode 100644
index 00000000000..9306a3d20e5
--- /dev/null
+++ b/extern/audaspace/include/fx/HighpassCalculator.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file HighpassCalculator.h
+ * @ingroup fx
+ * The HighpassCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The HighpassCalculator class calculates high pass filter coefficients for a
+ * dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL HighpassCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+ // delete copy constructor and operator=
+ HighpassCalculator(const HighpassCalculator&) = delete;
+ HighpassCalculator& operator=(const HighpassCalculator&) = delete;
+
+public:
+ /**
+ * Creates a HighpassCalculator object.
+ * @param frequency The cutoff frequency.
+ * @param Q The Q factor of the filter. If unsure, use 1.0 as default.
+ */
+ HighpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h b/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h
new file mode 100644
index 00000000000..6c890b313b4
--- /dev/null
+++ b/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDynamicIIRFilterCalculator.h
+ * @ingroup fx
+ * The IDynamicIIRFilterCalculator interface.
+ */
+
+#include "respec/Specification.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IDynamicIIRFilterCalculator
+ * This interface calculates dynamic filter coefficients which depend on the
+ * sampling rate for DynamicIIRFilterReaders.
+ */
+class AUD_API IDynamicIIRFilterCalculator
+{
+public:
+ virtual ~IDynamicIIRFilterCalculator() {}
+
+ /**
+ * Recalculates the filter coefficients.
+ * \param rate The sample rate of the audio data.
+ * \param[out] b The input filter coefficients.
+ * \param[out] a The output filter coefficients.
+ */
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float>& b, std::vector<float>& a)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IIRFilter.h b/extern/audaspace/include/fx/IIRFilter.h
new file mode 100644
index 00000000000..74099a30dc5
--- /dev/null
+++ b/extern/audaspace/include/fx/IIRFilter.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IIRFilter.h
+ * @ingroup fx
+ * The IIRFilter class.
+ */
+
+#include "fx/Effect.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a IIR filter reader.
+ */
+class AUD_API IIRFilter : public Effect
+{
+private:
+ /**
+ * Output filter coefficients.
+ */
+ std::vector<float> m_a;
+
+ /**
+ * Input filter coefficients.
+ */
+ std::vector<float> m_b;
+
+ // delete copy constructor and operator=
+ IIRFilter(const IIRFilter&) = delete;
+ IIRFilter& operator=(const IIRFilter&) = delete;
+
+public:
+ /**
+ * Creates a new IIR filter sound.
+ * \param sound The input sound.
+ * \param b The input filter coefficients.
+ * \param a The output filter coefficients.
+ */
+ IIRFilter(std::shared_ptr<ISound> sound, const std::vector<float>& b, const std::vector<float>& a);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IIRFilterReader.h b/extern/audaspace/include/fx/IIRFilterReader.h
new file mode 100644
index 00000000000..34518ce69c6
--- /dev/null
+++ b/extern/audaspace/include/fx/IIRFilterReader.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IIRFilterReader.h
+ * @ingroup fx
+ * The IIRFilterReader class.
+ */
+
+#include "fx/BaseIIRFilterReader.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is for infinite impulse response filters with simple coefficients.
+ */
+class AUD_API IIRFilterReader : public BaseIIRFilterReader
+{
+private:
+ /**
+ * Output filter coefficients.
+ */
+ std::vector<float> m_a;
+
+ /**
+ * Input filter coefficients.
+ */
+ std::vector<float> m_b;
+
+ // delete copy constructor and operator=
+ IIRFilterReader(const IIRFilterReader&) = delete;
+ IIRFilterReader& operator=(const IIRFilterReader&) = delete;
+
+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.
+ */
+ IIRFilterReader(std::shared_ptr<IReader> reader, const std::vector<float>& b, const std::vector<float>& a);
+
+ virtual sample_t filter();
+
+ /**
+ * Sets new filter coefficients.
+ * @param b The input filter coefficients.
+ * @param a The output filter coefficients.
+ */
+ void setCoefficients(const std::vector<float>& b, const std::vector<float>& a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ImpulseResponse.h b/extern/audaspace/include/fx/ImpulseResponse.h
new file mode 100644
index 00000000000..3cdb807ff99
--- /dev/null
+++ b/extern/audaspace/include/fx/ImpulseResponse.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ImpulseResponse.h
+* @ingroup fx
+* The ImpulseResponse class.
+*/
+
+#include "util/StreamBuffer.h"
+#include "util/FFTPlan.h"
+#include "IReader.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents an impulse response that can be used in convolution.
+* When this class is instanced, the impulse response is divided in channels and those channels are divided in parts of N/2 samples (N being the size of the FFT plan used).
+* The main objetive of this class is to allow the reutilization of an impulse response in various sounds without having to process it more than one time.
+* \warning The size of the FFTPlan used to process the impulse response must be the same as the one used in the convolver classes.
+*/
+class AUD_API ImpulseResponse
+{
+private:
+ /**
+ * A tri-dimensional array (channels, parts, values) The impulse response is divided in channels and those channels are divided
+ * in parts of N/2 samples. Those parts are transformed to the frequency domain transform which generates uni-dimensional
+ * arrays of fftwtf_complex data (complex numbers).
+ */
+ std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>>> m_processedIR;
+
+ /**
+ * The specification of the samples.
+ */
+ Specs m_specs;
+
+ /**
+ * The length of the impulse response.
+ */
+ int m_length;
+
+ // delete copy constructor and operator=
+ ImpulseResponse(const ImpulseResponse&) = delete;
+ ImpulseResponse& operator=(const ImpulseResponse&) = delete;
+
+public:
+ /**
+ * Creates a new ImpulseResponse object.
+ * The impulse response will be split and transformed to the frequency domain.
+ * \param impulseResponse The impulse response sound.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse response.
+ */
+ ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new ImpulseResponse object. This overload instances its own FFTPlan with default size.
+ * The impulse response will be split and transformed to the frequency domain.
+ * \param impulseResponse The impulse response sound.
+ */
+ ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse);
+
+ /**
+ * Returns the specification of the impulse response.
+ * \return The specification of the impulse response.
+ */
+ Specs getSpecs();
+
+ /**
+ * Retrieves the length of the impulse response.
+ * \return The length of the impulse response.
+ */
+ int getLength();
+
+ /**
+ * Retrieves one channel of the impulse response.
+ * \param n The desired channel number (from 0 to channels-1).
+ * \return The desired channel of the impulse response.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> getChannel(int n);
+
+private:
+ /**
+ * Processes the impulse response sound for its use in the convovler classes.
+ * \param A shared pointer to a reader of the desired sound.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse response.
+ */
+ void processImpulseResponse(std::shared_ptr<IReader> reader, std::shared_ptr<FFTPlan> plan);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Limiter.h b/extern/audaspace/include/fx/Limiter.h
new file mode 100644
index 00000000000..0b5451b4eed
--- /dev/null
+++ b/extern/audaspace/include/fx/Limiter.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Limiter.h
+ * @ingroup fx
+ * The Limiter class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound limits another sound in start and end time.
+ */
+class AUD_API Limiter : public Effect
+{
+private:
+ /**
+ * The start time.
+ */
+ const float m_start;
+
+ /**
+ * The end time.
+ */
+ const float m_end;
+
+ // delete copy constructor and operator=
+ Limiter(const Limiter&) = delete;
+ Limiter& operator=(const Limiter&) = delete;
+
+public:
+ /**
+ * Creates a new limiter sound.
+ * \param sound The input sound.
+ * \param start The desired start time.
+ * \param end The desired end time, a negative value signals that it should
+ * play to the end.
+ */
+ Limiter(std::shared_ptr<ISound> sound,
+ float start = 0, float end = -1);
+
+ /**
+ * Returns the start time.
+ */
+ float getStart() const;
+
+ /**
+ * Returns the end time.
+ */
+ float getEnd() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LimiterReader.h b/extern/audaspace/include/fx/LimiterReader.h
new file mode 100644
index 00000000000..49a07b5c29e
--- /dev/null
+++ b/extern/audaspace/include/fx/LimiterReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LimiterReader.h
+ * @ingroup fx
+ * The LimiterReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader limits another reader in start and end times.
+ */
+class AUD_API LimiterReader : public EffectReader
+{
+private:
+ /**
+ * The start sample: inclusive.
+ */
+ const float m_start;
+
+ /**
+ * The end sample: exlusive.
+ */
+ const float m_end;
+
+ // delete copy constructor and operator=
+ LimiterReader(const LimiterReader&) = delete;
+ LimiterReader& operator=(const LimiterReader&) = delete;
+
+public:
+ /**
+ * Creates a new limiter reader.
+ * \param reader The reader to read from.
+ * \param start The desired start time (inclusive).
+ * \param end The desired end time (sample exklusive), a negative value
+ * signals that it should play to the end.
+ */
+ LimiterReader(std::shared_ptr<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, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Loop.h b/extern/audaspace/include/fx/Loop.h
new file mode 100644
index 00000000000..c8ba7609f23
--- /dev/null
+++ b/extern/audaspace/include/fx/Loop.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Loop.h
+ * @ingroup fx
+ * The Loop class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound loops another sound.
+ * \note The reader has to be seekable.
+ */
+class AUD_API Loop : public Effect
+{
+private:
+ /**
+ * The loop count.
+ */
+ const int m_loop;
+
+ // delete copy constructor and operator=
+ Loop(const Loop&) = delete;
+ Loop& operator=(const Loop&) = delete;
+
+public:
+ /**
+ * Creates a new loop sound.
+ * \param sound The input sound.
+ * \param loop The desired loop count, negative values result in endless
+ * looping.
+ */
+ Loop(std::shared_ptr<ISound> sound, int loop = -1);
+
+ /**
+ * Returns the loop count.
+ */
+ int getLoop() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LoopReader.h b/extern/audaspace/include/fx/LoopReader.h
new file mode 100644
index 00000000000..72bb92c8b8f
--- /dev/null
+++ b/extern/audaspace/include/fx/LoopReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LoopReader.h
+ * @ingroup fx
+ * The LoopReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and loops it.
+ * \note The other reader must be seekable.
+ */
+class AUD_API LoopReader : public EffectReader
+{
+private:
+ /**
+ * The loop count.
+ */
+ const int m_count;
+
+ /**
+ * The left loop count.
+ */
+ int m_left;
+
+ // delete copy constructor and operator=
+ LoopReader(const LoopReader&) = delete;
+ LoopReader& operator=(const LoopReader&) = delete;
+
+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.
+ */
+ LoopReader(std::shared_ptr<IReader> reader, int loop);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Lowpass.h b/extern/audaspace/include/fx/Lowpass.h
new file mode 100644
index 00000000000..c14e5e8e0e2
--- /dev/null
+++ b/extern/audaspace/include/fx/Lowpass.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Lowpass.h
+ * @ingroup fx
+ * The Lowpass class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a lowpass filter reader.
+ */
+class AUD_API Lowpass : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Lowpass(const Lowpass&) = delete;
+ Lowpass& operator=(const Lowpass&) = delete;
+
+public:
+ /**
+ * Creates a new lowpass sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ Lowpass(std::shared_ptr<ISound> sound, float frequency, float Q = 1.0f);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LowpassCalculator.h b/extern/audaspace/include/fx/LowpassCalculator.h
new file mode 100644
index 00000000000..477adfb5b5b
--- /dev/null
+++ b/extern/audaspace/include/fx/LowpassCalculator.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LowpassCalculator.h
+ * @ingroup fx
+ * The LowpassCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The LowpassCalculator class calculates low pass filter coefficients for a
+ * dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL LowpassCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+ // delete copy constructor and operator=
+ LowpassCalculator(const LowpassCalculator&) = delete;
+ LowpassCalculator& operator=(const LowpassCalculator&) = delete;
+
+public:
+ /**
+ * Creates a LowpassCalculator object.
+ * @param frequency The cutoff frequency.
+ * @param Q The Q factor of the filter. If unsure, use 1.0 as default.
+ */
+ LowpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/MutableReader.h b/extern/audaspace/include/fx/MutableReader.h
new file mode 100644
index 00000000000..217dd2aa5d4
--- /dev/null
+++ b/extern/audaspace/include/fx/MutableReader.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file MutableReader.h
+* @ingroup fx
+* The MutableReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can change with each playback. The change will occur when trying to seek backwards
+* If the sound doesn't support that, it will be restarted.
+* \warning Notice that if a SoundList object is assigned to several MutableReaders, sequential playback won't work correctly.
+* To prevent this the SoundList must be copied.
+*/
+class AUD_API MutableReader : public IReader
+{
+private:
+ /**
+ * The current reader.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * A sound from which to get the reader.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+
+ // delete copy constructor and operator=
+ MutableReader(const MutableReader&) = delete;
+ MutableReader& operator=(const MutableReader&) = delete;
+
+public:
+ /**
+ * Creates a new mutable reader.
+ * \param sound A of sound you want to assign to this reader.
+ */
+ MutableReader(std::shared_ptr<ISound> sound);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/MutableSound.h b/extern/audaspace/include/fx/MutableSound.h
new file mode 100644
index 00000000000..9b5aa95cf18
--- /dev/null
+++ b/extern/audaspace/include/fx/MutableSound.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file MutableSound.h
+* @ingroup fx
+* The MutableSound class.
+*/
+
+#include "ISound.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* Ths class allows to create MutableReaders for any sound.
+*/
+class AUD_API MutableSound : public ISound
+{
+private:
+ /**
+ * A pointer to a sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ // delete copy constructor and operator=
+ MutableSound(const MutableSound&) = delete;
+ MutableSound& operator=(const MutableSound&) = delete;
+
+public:
+ /**
+ * Creates a new MutableSound.
+ * \param sound The sound in which the MutabeReaders created with the createReader() method will be based.
+ * If shared pointer to a SoundList object is used in several mutable sounds the sequential
+ * playback will not work properly. A copy of the SoundList object must be made in this case.
+ */
+ MutableSound(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Pitch.h b/extern/audaspace/include/fx/Pitch.h
new file mode 100644
index 00000000000..570366be549
--- /dev/null
+++ b/extern/audaspace/include/fx/Pitch.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Pitch.h
+ * @ingroup fx
+ * The Pitch class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound changes the pitch of another sound.
+ */
+class AUD_API Pitch : public Effect
+{
+private:
+ /**
+ * The pitch.
+ */
+ const float m_pitch;
+
+ // delete copy constructor and operator=
+ Pitch(const Pitch&) = delete;
+ Pitch& operator=(const Pitch&) = delete;
+
+public:
+ /**
+ * Creates a new pitch sound.
+ * \param sound The input sound.
+ * \param pitch The desired pitch.
+ */
+ Pitch(std::shared_ptr<ISound> sound, float pitch);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PitchReader.h b/extern/audaspace/include/fx/PitchReader.h
new file mode 100644
index 00000000000..c82f71b61bf
--- /dev/null
+++ b/extern/audaspace/include/fx/PitchReader.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PitchReader.h
+ * @ingroup fx
+ * The PitchReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and changes it's pitch.
+ */
+class AUD_API PitchReader : public EffectReader
+{
+private:
+ /**
+ * The pitch level.
+ */
+ float m_pitch;
+
+ // delete copy constructor and operator=
+ PitchReader(const PitchReader&) = delete;
+ PitchReader& operator=(const PitchReader&) = delete;
+
+public:
+ /**
+ * Creates a new pitch reader.
+ * \param reader The reader to read from.
+ * \param pitch The pitch value.
+ */
+ PitchReader(std::shared_ptr<IReader> reader, float pitch);
+
+ virtual Specs getSpecs() const;
+
+ /**
+ * Retrieves the pitch.
+ * \return The current pitch value.
+ */
+ float getPitch() const;
+
+ /**
+ * Sets the pitch.
+ * \param pitch The new pitch value.
+ */
+ void setPitch(float pitch);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PlaybackCategory.h b/extern/audaspace/include/fx/PlaybackCategory.h
new file mode 100644
index 00000000000..7721623359f
--- /dev/null
+++ b/extern/audaspace/include/fx/PlaybackCategory.h
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file PlaybackCategory.h
+* @ingroup fx
+* The PlaybackCategory class.
+*/
+
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "VolumeStorage.h"
+
+#include <unordered_map>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a category of related sounds which are currently playing and allows to control them easily.
+*/
+class AUD_API PlaybackCategory
+{
+private:
+ /**
+ * Next handle ID to be assigned.
+ */
+ unsigned int m_currentID;
+
+ /**
+ * Vector of handles that belong to the category.
+ */
+ std::unordered_map<unsigned int, std::shared_ptr<IHandle>> m_handles;
+
+ /**
+ * Device that will play the sounds.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * Status of the category.
+ */
+ Status m_status;
+
+ /**
+ * Volume of all the sounds of the category.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+ // delete copy constructor and operator=
+ PlaybackCategory(const PlaybackCategory&) = delete;
+ PlaybackCategory& operator=(const PlaybackCategory&) = delete;
+
+public:
+ /**
+ * Creates a new PlaybackCategory.
+ * \param device A shared pointer to the device which will be used for playback.
+ */
+ PlaybackCategory(std::shared_ptr<IDevice> device);
+ ~PlaybackCategory();
+
+ /**
+ * Plays a new sound in the category.
+ * \param sound The sound to be played.
+ * \return A handle for the playback. If the playback failed, nullptr will be returned.
+ */
+ std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound);
+
+ /**
+ * Resumes all the paused sounds of the category.
+ */
+ void resume();
+
+ /**
+ * Pauses all current played back sounds of the category.
+ */
+ void pause();
+
+ /**
+ * Retrieves the volume of the category.
+ * \return The volume.
+ */
+ float getVolume();
+
+ /**
+ * Sets the volume for the category.
+ * \param volume The volume.
+ */
+ void setVolume(float volume);
+
+ /**
+ * Stops all the playing back or paused sounds.
+ */
+ void stop();
+
+ /**
+ * Retrieves the shared volume of the category.
+ * \return A shared pointer to the VolumeStorage object that represents the shared volume of the category.
+ */
+ std::shared_ptr<VolumeStorage> getSharedVolume();
+
+ /**
+ * Cleans the category erasing all the invalid handles.
+ * Only needed if individual sounds are stopped with their handles.
+ */
+ void cleanHandles();
+
+private:
+ static void cleanHandleCallback(void* data);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PlaybackManager.h b/extern/audaspace/include/fx/PlaybackManager.h
new file mode 100644
index 00000000000..f660568b8db
--- /dev/null
+++ b/extern/audaspace/include/fx/PlaybackManager.h
@@ -0,0 +1,156 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file PlaybackManager.h
+* @ingroup fx
+* The PlaybackManager class.
+*/
+
+#include "PlaybackCategory.h"
+#include "devices/IDevice.h"
+#include "ISound.h"
+
+#include <unordered_map>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to control groups of playing sounds easily.
+* The sounds are part of categories.
+*/
+class AUD_API PlaybackManager
+{
+private:
+ /**
+ * Unordered map of categories, each category has different name.
+ */
+ std::unordered_map<unsigned int, std::shared_ptr<PlaybackCategory>> m_categories;
+
+ /**
+ * Device used for playback.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * The current key used for new categories.
+ */
+ unsigned int m_currentKey;
+
+ // delete copy constructor and operator=
+ PlaybackManager(const PlaybackManager&) = delete;
+ PlaybackManager& operator=(const PlaybackManager&) = delete;
+
+public:
+ /**
+ * Creates a new PlaybackManager.
+ * \param device A shared pointer to the device which will be used for playback.
+ */
+ PlaybackManager(std::shared_ptr<IDevice> device);
+
+ /**
+ * Adds an existent category to the manager and returns a key to access it.
+ * \param category The category to be added.
+ * \return The category key.
+ */
+ unsigned int addCategory(std::shared_ptr<PlaybackCategory> category);
+
+ /**
+ * Adds an existent category to the manager and returns a key to access it.
+ * \param volume The volume of the new category.
+ * \return The category key.
+ */
+ unsigned int addCategory(float volume);
+
+ /**
+ * Plays a sound and adds it to a new or existent category.
+ * \param sound The sound to be played and added to a category.
+ * \param catKey Key of the category.
+ * \return The handle of the playback; nullptr if the sound couldn't be played.
+ */
+ std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, unsigned int catKey);
+
+ /**
+ * Resumes all the paused sounds of a category.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool resume(unsigned int catKey);
+
+ /**
+ * Pauses all current playing sounds of a category.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool pause(unsigned int catKey);
+
+ /**
+ * Retrieves the volume of a category.
+ * \param catKey Key of the category.
+ * \return The volume value of the category. If the category doesn't exist it returns a negative number.
+ */
+ float getVolume(unsigned int catKey);
+
+ /**
+ * Sets the volume for a category.
+ * \param volume The volume.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool setVolume(float volume, unsigned int catKey);
+
+ /**
+ * Stops and erases a category of sounds.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool stop(unsigned int catKey);
+
+ /**
+ * Removes all the invalid handles of all the categories.
+ * Only needed if individual sounds are stopped with their handles.
+ */
+ void clean();
+
+ /**
+ * Removes all the invalid handles of a category.
+ * Only needed if individual sounds are stopped with their handles.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool clean(unsigned int catKey);
+
+ /**
+ * Retrieves the device of the PlaybackManager.
+ * \return A shared pointer to the device used by the playback manager.
+ */
+ std::shared_ptr<IDevice> getDevice();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Reverse.h b/extern/audaspace/include/fx/Reverse.h
new file mode 100644
index 00000000000..32227da977a
--- /dev/null
+++ b/extern/audaspace/include/fx/Reverse.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Reverse.h
+ * @ingroup fx
+ * The Reverse class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound reads another sound reverted.
+ * \note Readers from the underlying sound must be seekable.
+ */
+class AUD_API Reverse : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ Reverse(const Reverse&) = delete;
+ Reverse& operator=(const Reverse&) = delete;
+
+public:
+ /**
+ * Creates a new reverse sound.
+ * \param sound The input sound.
+ */
+ Reverse(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ReverseReader.h b/extern/audaspace/include/fx/ReverseReader.h
new file mode 100644
index 00000000000..a02608e1378
--- /dev/null
+++ b/extern/audaspace/include/fx/ReverseReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ReverseReader.h
+ * @ingroup fx
+ * The ReverseReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader from back to front.
+ * \note The underlying reader must be seekable.
+ */
+class AUD_API ReverseReader : public EffectReader
+{
+private:
+ /**
+ * The sample count.
+ */
+ const int m_length;
+
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ // delete copy constructor and operator=
+ ReverseReader(const ReverseReader&) = delete;
+ ReverseReader& operator=(const ReverseReader&) = delete;
+
+public:
+ /**
+ * Creates a new reverse reader.
+ * \param reader The reader to read from.
+ * \exception Exception Thrown if the reader specified has an
+ * undeterminable/infinite length or is not seekable.
+ */
+ ReverseReader(std::shared_ptr<IReader> reader);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/SoundList.h b/extern/audaspace/include/fx/SoundList.h
new file mode 100644
index 00000000000..ce3cb386969
--- /dev/null
+++ b/extern/audaspace/include/fx/SoundList.h
@@ -0,0 +1,110 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file SoundList.h
+* @ingroup fx
+* The SoundList class.
+*/
+
+#include "ISound.h"
+
+#include <vector>
+#include <memory>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to have a list of sound that will play sequentially or randomly with each playback.
+*/
+class AUD_API SoundList : public ISound
+{
+private:
+ /**
+ * The list of sounds that will play.
+ */
+ std::vector<std::shared_ptr<ISound>> m_list;
+
+ /**
+ * Flag for random playback
+ */
+ bool m_random = false;
+
+ /**
+ * Current sound index. -1 if no reader has been created.
+ */
+ int m_index = -1;
+
+ /**
+ * Mutex to prevent multithreading crashes.
+ */
+ std::recursive_mutex m_mutex;
+
+ // delete copy constructor and operator=
+ SoundList(const SoundList&) = delete;
+ SoundList& operator=(const SoundList&) = delete;
+
+public:
+ /**
+ * Creates a new, empty sound list.
+ * Sounds must be added to the list using the addSound() method.
+ * \param random False if the sounds int he list must be played sequentially. True if random.
+ */
+ SoundList(bool random = false);
+
+ /**
+ * Creates a new sound list and initializes it.
+ * \param list A vector with sounds to initialize the list.
+ * \param random False if the sounds int he list must be played sequentially. True if random.
+ */
+ SoundList(std::vector<std::shared_ptr<ISound>>& list, bool random = false);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Adds a sound to the list.
+ * The added sounds can be played sequentially or randomly dependig
+ * on the m_random flag
+ * \param sound A shared_ptr to the sound.
+ */
+ void addSound(std::shared_ptr<ISound> sound);
+
+ /**
+ * Sets the playback mode of the sound list.
+ * There are two posible modes, random and sequential.
+ * \param random True to activate the random mode, false to activate sequential mode.
+ */
+ void setRandomMode(bool random);
+
+ /**
+ * Returns the playback mode of the sound list.
+ * The two posible modes are random and sequential.
+ * \return True if the random mode is activated, false otherwise.
+ */
+ bool getRandomMode();
+
+ /**
+ * Returns the amount of sounds in the list.
+ * \return The amount of sounds in the list.
+ */
+ int getSize();
+
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Source.h b/extern/audaspace/include/fx/Source.h
new file mode 100644
index 00000000000..84448aa669d
--- /dev/null
+++ b/extern/audaspace/include/fx/Source.h
@@ -0,0 +1,109 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Source.h
+* @ingroup fx
+* The Source class.
+*/
+
+#include "Audaspace.h"
+
+#include <atomic>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class stores the azimuth and elevation angles of a sound and allows to change them dynamically.
+* The azimuth angle goes clockwise. For a sound source situated at the right of the listener the azimuth angle is 90.
+*/
+class AUD_API Source
+{
+private:
+ /**
+ * Azimuth value.
+ */
+ std::atomic<float> m_azimuth;
+
+ /**
+ * Elevation value.
+ */
+ std::atomic<float> m_elevation;
+
+ /**
+ * Distance value. Between 0 and 1.
+ */
+ std::atomic<float> m_distance;
+
+ // delete copy constructor and operator=
+ Source(const Source&) = delete;
+ Source& operator=(const Source&) = delete;
+
+public:
+ /**
+ * Creates a Source instance with an initial value.
+ * \param azimuth The value of the azimuth.
+ * \param elevation The value of the elevation.
+ * \param distance The distance from the listener. Max distance is 1, min distance is 0.
+ */
+ Source(float azimuth, float elevation, float distance = 0.0);
+
+ /**
+ * Retrieves the current azimuth value.
+ * \return The current azimuth.
+ */
+ float getAzimuth();
+
+ /**
+ * Retrieves the current elevation value.
+ * \return The current elevation.
+ */
+ float getElevation();
+
+ /**
+ * Retrieves the current distance value.
+ * \return The current distance.
+ */
+ float getDistance();
+
+ /**
+ * Retrieves the current volume value based on the distance.
+ * \return The current volume based on the Distance.
+ */
+ float getVolume();
+
+ /**
+ * Changes the azimuth value.
+ * \param azimuth The new value for the azimuth.
+ */
+ void setAzimuth(float azimuth);
+
+ /**
+ * Changes the elevation value.
+ * \param elevation The new value for the elevation.
+ */
+ void setElevation(float elevation);
+
+ /**
+ * Changes the distance value.
+ * \param distance The new value for the distance. Max distance is 1, min distance is 0.
+ */
+ void setDistance(float distance);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Sum.h b/extern/audaspace/include/fx/Sum.h
new file mode 100644
index 00000000000..b590aa7fcd1
--- /dev/null
+++ b/extern/audaspace/include/fx/Sum.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sum.h
+ * @ingroup fx
+ * The Sum class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a sum reader.
+ */
+class AUD_API Sum : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ Sum(const Sum&) = delete;
+ Sum& operator=(const Sum&) = delete;
+
+public:
+ /**
+ * Creates a new sum sound.
+ * \param sound The input sound.
+ */
+ Sum(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Threshold.h b/extern/audaspace/include/fx/Threshold.h
new file mode 100644
index 00000000000..10baef1714d
--- /dev/null
+++ b/extern/audaspace/include/fx/Threshold.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Threshold.h
+ * @ingroup fx
+ * The Threshold class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * This sound Transforms any signal to a square signal by thresholding.
+ */
+class AUD_API Threshold : public Effect
+{
+private:
+ /**
+ * The threshold.
+ */
+ const float m_threshold;
+
+ // delete copy constructor and operator=
+ Threshold(const Threshold&) = delete;
+ Threshold& operator=(const Threshold&) = delete;
+
+public:
+ /**
+ * Creates a new threshold sound.
+ * \param sound The input sound.
+ * \param threshold The threshold.
+ */
+ Threshold(std::shared_ptr<ISound> sound, float threshold = 0.0f);
+
+ /**
+ * Returns the threshold.
+ */
+ float getThreshold() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The thresholdFilter function implements the doFilterIIR callback
+ * for the callback IIR filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param threshold The threshold value.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL thresholdFilter(CallbackIIRFilterReader* reader, float* threshold);
+
+ /**
+ * The endThresholdFilter function implements the endFilterIIR callback
+ * for the callback IIR filter.
+ * @param threshold The threshold value.
+ */
+ static void AUD_LOCAL endThresholdFilter(float* threshold);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Volume.h b/extern/audaspace/include/fx/Volume.h
new file mode 100644
index 00000000000..0e56e8efd9b
--- /dev/null
+++ b/extern/audaspace/include/fx/Volume.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Volume.h
+ * @ingroup fx
+ * The Volume class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound changes the volume of another sound.
+ * The set volume should be a value between 0.0 and 1.0, higher values at your
+ * own risk!
+ */
+class AUD_API Volume : public Effect
+{
+private:
+ /**
+ * The volume.
+ */
+ const float m_volume;
+
+ // delete copy constructor and operator=
+ Volume(const Volume&) = delete;
+ Volume& operator=(const Volume&) = delete;
+
+public:
+ /**
+ * Creates a new volume sound.
+ * \param sound The input sound.
+ * \param volume The desired volume.
+ */
+ Volume(std::shared_ptr<ISound> sound, float volume);
+
+ /**
+ * Returns the volume.
+ * \return The current volume.
+ */
+ float getVolume() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/VolumeReader.h b/extern/audaspace/include/fx/VolumeReader.h
new file mode 100644
index 00000000000..13b6845e931
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeReader.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeReader.h
+* @ingroup fx
+* The VolumeReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "VolumeStorage.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that has its own shared volume
+*/
+class AUD_API VolumeReader : public IReader
+{
+private:
+ /**
+ * The current reader.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * A sound from which to get the reader.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+
+ // delete copy constructor and operator=
+ VolumeReader(const VolumeReader&) = delete;
+ VolumeReader& operator=(const VolumeReader&) = delete;
+
+public:
+ /**
+ * Creates a new volume reader.
+ * \param reader A reader of the sound to be assigned to this reader.
+ * \param volumeStorage A shared pointer to a VolumeStorage object.
+ */
+ VolumeReader(std::shared_ptr<IReader> reader, std::shared_ptr<VolumeStorage> volumeStorage);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/VolumeSound.h b/extern/audaspace/include/fx/VolumeSound.h
new file mode 100644
index 00000000000..0aeffd53e87
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeSound.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeSound.h
+* @ingroup fx
+* The VolumeSound class.
+*/
+
+#include "ISound.h"
+#include "VolumeStorage.h"
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to create a sound with its own volume.
+*/
+class AUD_API VolumeSound : public ISound
+{
+private:
+ /**
+ * A pointer to a sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to the shared volume being used.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+ // delete copy constructor and operator=
+ VolumeSound(const VolumeSound&) = delete;
+ VolumeSound& operator=(const VolumeSound&) = delete;
+
+public:
+ /**
+ * Creates a new VolumeSound.
+ * \param sound The sound in which shall have its own volume.
+ * \param volumeStorage A shared pointer to a VolumeStorage object. It allows to change the volume of various sound in one go.
+ */
+ VolumeSound(std::shared_ptr<ISound> sound, std::shared_ptr<VolumeStorage> volumeStorage);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the shared volume of this sound.
+ * \return A shared pointer to the VolumeStorage object that this sound is using.
+ */
+ std::shared_ptr<VolumeStorage> getSharedVolume();
+
+ /**
+ * Changes the shared volume of this sound, it'll only affect newly created readers.
+ * \param volumeStorage A shared pointer to the new VolumeStorage object.
+ */
+ void setSharedVolume(std::shared_ptr<VolumeStorage> volumeStorage);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/VolumeStorage.h b/extern/audaspace/include/fx/VolumeStorage.h
new file mode 100644
index 00000000000..5088a5e2ba9
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeStorage.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeStorage.h
+* @ingroup fx
+* The VolumeStorage class.
+*/
+
+#include "Audaspace.h"
+
+#include <atomic>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class stores a volume value and allows to change if for a number of sounds in one go.
+*/
+class AUD_API VolumeStorage
+{
+private:
+ /**
+ * Volume value.
+ */
+ std::atomic<float> m_volume;
+
+ // delete copy constructor and operator=
+ VolumeStorage(const VolumeStorage&) = delete;
+ VolumeStorage& operator=(const VolumeStorage&) = delete;
+
+public:
+ /**
+ * Creates a new VolumeStorage instance with volume 1
+ */
+ VolumeStorage();
+
+ /**
+ * Creates a VolumeStorage instance with an initial value.
+ * \param volume The value of the volume.
+ */
+ VolumeStorage(float volume);
+
+ /**
+ * Retrieves the current volume value.
+ * \return The current volume.
+ */
+ float getVolume();
+
+ /**
+ * Changes the volume value.
+ * \param volume The new value for the volume.
+ */
+ void setVolume(float volume);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Sawtooth.h b/extern/audaspace/include/generator/Sawtooth.h
new file mode 100644
index 00000000000..68f56ae83fd
--- /dev/null
+++ b/extern/audaspace/include/generator/Sawtooth.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sawtooth.h
+ * @ingroup generator
+ * The Sawtooth class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a sawtooth tone.
+ */
+class AUD_API Sawtooth : public ISound
+{
+private:
+ /**
+ * The frequence of the sawtooth wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Sawtooth(const Sawtooth&) = delete;
+ Sawtooth& operator=(const Sawtooth&) = delete;
+
+public:
+ /**
+ * Creates a new sawtooth sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Sawtooth(float frequency, SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the sawtooth wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SawtoothReader.h b/extern/audaspace/include/generator/SawtoothReader.h
new file mode 100644
index 00000000000..b4045eb8820
--- /dev/null
+++ b/extern/audaspace/include/generator/SawtoothReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SawtoothReader.h
+ * @ingroup generator
+ * The SawtoothReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sawtooth tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API SawtoothReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SawtoothReader(const SawtoothReader&) = delete;
+ SawtoothReader& operator=(const SawtoothReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SawtoothReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Silence.h b/extern/audaspace/include/generator/Silence.h
new file mode 100644
index 00000000000..a35b83d37fc
--- /dev/null
+++ b/extern/audaspace/include/generator/Silence.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Silence.h
+ * @ingroup generator
+ * The Silence class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays silence.
+ */
+class AUD_API Silence : public ISound
+{
+private:
+ // delete copy constructor and operator=
+ Silence(const Silence&) = delete;
+ Silence& operator=(const Silence&) = delete;
+
+public:
+ /**
+ * Creates a new silence sound.
+ */
+ Silence();
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SilenceReader.h b/extern/audaspace/include/generator/SilenceReader.h
new file mode 100644
index 00000000000..ecc0ce86da9
--- /dev/null
+++ b/extern/audaspace/include/generator/SilenceReader.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SilenceReader.h
+ * @ingroup generator
+ * The SilenceReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for silence playback.
+ * The signal generated is 44.1kHz mono.
+ */
+class AUD_API SilenceReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ // delete copy constructor and operator=
+ SilenceReader(const SilenceReader&) = delete;
+ SilenceReader& operator=(const SilenceReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ */
+ SilenceReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Sine.h b/extern/audaspace/include/generator/Sine.h
new file mode 100644
index 00000000000..ee78fc7d06b
--- /dev/null
+++ b/extern/audaspace/include/generator/Sine.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sine.h
+ * @ingroup generator
+ * The Sine class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a sine tone.
+ */
+class AUD_API Sine : public ISound
+{
+private:
+ /**
+ * The frequence of the sine wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Sine(const Sine&) = delete;
+ Sine& operator=(const Sine&) = delete;
+
+public:
+ /**
+ * Creates a new sine sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Sine(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the sine wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SineReader.h b/extern/audaspace/include/generator/SineReader.h
new file mode 100644
index 00000000000..49cd571bc65
--- /dev/null
+++ b/extern/audaspace/include/generator/SineReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SineReader.h
+ * @ingroup generator
+ * The SineReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sine tone playback.
+ * The sample rate can be specified, the signal is mono.
+ */
+class AUD_API SineReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SineReader(const SineReader&) = delete;
+ SineReader& operator=(const SineReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SineReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Square.h b/extern/audaspace/include/generator/Square.h
new file mode 100644
index 00000000000..0ba27677a81
--- /dev/null
+++ b/extern/audaspace/include/generator/Square.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Square.h
+ * @ingroup generator
+ * The Square class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a square tone.
+ */
+class AUD_API Square : public ISound
+{
+private:
+ /**
+ * The frequence of the square wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Square(const Square&) = delete;
+ Square& operator=(const Square&) = delete;
+
+public:
+ /**
+ * Creates a new square sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Square(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the square wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SquareReader.h b/extern/audaspace/include/generator/SquareReader.h
new file mode 100644
index 00000000000..53fc574c767
--- /dev/null
+++ b/extern/audaspace/include/generator/SquareReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SquareReader.h
+ * @ingroup generator
+ * The SquareReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for square tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API SquareReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SquareReader(const SquareReader&) = delete;
+ SquareReader& operator=(const SquareReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SquareReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Triangle.h b/extern/audaspace/include/generator/Triangle.h
new file mode 100644
index 00000000000..4f607fc23b5
--- /dev/null
+++ b/extern/audaspace/include/generator/Triangle.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Triangle.h
+ * @ingroup generator
+ * The Triangle class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a triangle tone.
+ */
+class AUD_API Triangle : public ISound
+{
+private:
+ /**
+ * The frequence of the triangle wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Triangle(const Triangle&) = delete;
+ Triangle& operator=(const Triangle&) = delete;
+
+public:
+ /**
+ * Creates a new triangle sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Triangle(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the triangle wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/TriangleReader.h b/extern/audaspace/include/generator/TriangleReader.h
new file mode 100644
index 00000000000..15079404b75
--- /dev/null
+++ b/extern/audaspace/include/generator/TriangleReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file TriangleReader.h
+ * @ingroup generator
+ * The TriangleReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sawtooth tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API TriangleReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ TriangleReader(const TriangleReader&) = delete;
+ TriangleReader& operator=(const TriangleReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ TriangleReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/plugin/PluginManager.h b/extern/audaspace/include/plugin/PluginManager.h
new file mode 100644
index 00000000000..af2f469c4ea
--- /dev/null
+++ b/extern/audaspace/include/plugin/PluginManager.h
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PluginManager.h
+ * @ingroup plugin
+ * The PluginManager class.
+ */
+
+#include "Audaspace.h"
+
+#include <unordered_map>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This manager provides utilities for plugin loading.
+ */
+class AUD_API PluginManager
+{
+private:
+ static std::unordered_map<std::string, void*> m_plugins;
+
+ // delete copy constructor and operator=
+ PluginManager(const PluginManager&) = delete;
+ PluginManager& operator=(const PluginManager&) = delete;
+ PluginManager() = delete;
+
+public:
+ /**
+ * Opens a shared library.
+ * @param path The path to the file.
+ * @return A handle to the library or nullptr if opening failed.
+ */
+ static void* openLibrary(const std::string& path);
+
+ /**
+ * Looks up a symbol from an opened library.
+ * @param handle The handle to the opened library.
+ * @param name The name of the symbol to look up.
+ * @return The symbol or nullptr if the symbol was not found.
+ */
+ static void* lookupLibrary(void* handle, const std::string& name);
+
+ /**
+ * Closes an opened shared library.
+ * @param handle The handle to the library to be closed.
+ */
+ static void closeLibrary(void* handle);
+
+ /**
+ * Loads a plugin from a file.
+ * @param path The path to the file.
+ * @return Whether the file could successfully be loaded.
+ */
+ static bool loadPlugin(const std::string& path);
+
+ /**
+ * Loads all plugins found in a folder.
+ * @param path The path to the folder containing the plugins.
+ */
+ static void loadPlugins(const std::string& path = "");
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ChannelMapper.h b/extern/audaspace/include/respec/ChannelMapper.h
new file mode 100644
index 00000000000..5481a42c433
--- /dev/null
+++ b/extern/audaspace/include/respec/ChannelMapper.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ChannelMapper.h
+ * @ingroup respec
+ * The ChannelMapper class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that maps a sound source's channels to a
+ * specific output channel count.
+ */
+class AUD_API ChannelMapper : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ ChannelMapper(const ChannelMapper&) = delete;
+ ChannelMapper& operator=(const ChannelMapper&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ ChannelMapper(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ChannelMapperReader.h b/extern/audaspace/include/respec/ChannelMapperReader.h
new file mode 100644
index 00000000000..00739ee995f
--- /dev/null
+++ b/extern/audaspace/include/respec/ChannelMapperReader.h
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ChannelMapperReader.h
+ * @ingroup respec
+ * The ChannelMapperReader class.
+ */
+
+#include "fx/EffectReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class maps a sound source's channels to a specific output channel count.
+ * \note The input sample format must be float.
+ */
+class AUD_API ChannelMapperReader : public EffectReader
+{
+private:
+ /**
+ * The sound reading buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The output specification.
+ */
+ Channels m_target_channels;
+
+ /**
+ * The channel count of the reader.
+ */
+ Channels m_source_channels;
+
+ /**
+ * The mapping specification.
+ */
+ float* m_mapping;
+
+ /**
+ * The size of the mapping.
+ */
+ int m_map_size;
+
+ /**
+ * The mono source angle.
+ */
+ float m_mono_angle;
+
+ static const Channel MONO_MAP[];
+ static const Channel STEREO_MAP[];
+ static const Channel STEREO_LFE_MAP[];
+ static const Channel SURROUND4_MAP[];
+ static const Channel SURROUND5_MAP[];
+ static const Channel SURROUND51_MAP[];
+ static const Channel SURROUND61_MAP[];
+ static const Channel SURROUND71_MAP[];
+ static const Channel* CHANNEL_MAPS[];
+
+ static const float MONO_ANGLES[];
+ static const float STEREO_ANGLES[];
+ static const float STEREO_LFE_ANGLES[];
+ static const float SURROUND4_ANGLES[];
+ static const float SURROUND5_ANGLES[];
+ static const float SURROUND51_ANGLES[];
+ static const float SURROUND61_ANGLES[];
+ static const float SURROUND71_ANGLES[];
+ static const float* CHANNEL_ANGLES[];
+
+ // delete copy constructor and operator=
+ ChannelMapperReader(const ChannelMapperReader&) = delete;
+ ChannelMapperReader& operator=(const ChannelMapperReader&) = delete;
+
+ /**
+ * Calculates the mapping matrix.
+ */
+ void AUD_LOCAL calculateMapping();
+
+ /**
+ * Calculates the distance between two angles.
+ */
+ float AUD_LOCAL angleDistance(float alpha, float beta);
+
+public:
+ /**
+ * Creates a channel mapper reader.
+ * \param reader The reader to map.
+ * \param channels The target channel count this reader should map to.
+ */
+ ChannelMapperReader(std::shared_ptr<IReader> reader, Channels channels);
+
+ /**
+ * Destroys the reader.
+ */
+ ~ChannelMapperReader();
+
+ /**
+ * Returns the channel configuration of the source reader.
+ * @return The channel configuration of the reader.
+ */
+ Channels getSourceChannels() const;
+
+ /**
+ * Returns the target channel configuration.
+ * Equals getSpecs().channels.
+ * @return The target channel configuration.
+ */
+ Channels getChannels() const;
+
+ /**
+ * Sets the requested channel output count.
+ * \param channels The channel output count.
+ */
+ void setChannels(Channels channels);
+
+ /**
+ * Returns the mapping of the source channel to the target channel.
+ * @param source The number of the source channel. Should be in the range [0, source channels).
+ * @param target The number of the target channel. Should be in the range [0, target channels).
+ * @return The mapping value which should be between 0.0 and 1.0. If source or target are out of range, NaN is returned.
+ */
+ float getMapping(int source, int target);
+
+ /**
+ * Sets the angle for mono sources.
+ * \param angle The angle for mono sources.
+ */
+ void setMonoAngle(float angle);
+
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Converter.h b/extern/audaspace/include/respec/Converter.h
new file mode 100644
index 00000000000..35664b28025
--- /dev/null
+++ b/extern/audaspace/include/respec/Converter.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Converter.h
+ * @ingroup respec
+ * The Converter class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a converter reader that is able to convert from one
+ * audio format to another.
+ */
+class AUD_API Converter : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ Converter(const Converter&) = delete;
+ Converter& operator=(const Converter&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ Converter(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ConverterFunctions.h b/extern/audaspace/include/respec/ConverterFunctions.h
new file mode 100644
index 00000000000..3cc4a713cc9
--- /dev/null
+++ b/extern/audaspace/include/respec/ConverterFunctions.h
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ConverterFunctions.h
+ * @ingroup respec
+ * Defines several conversion functions between different sample formats.
+ */
+
+#include "Audaspace.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The function template for functions converting from one sample format
+ * to another, having the same parameter order as std::memcpy.
+ */
+typedef void (*convert_f)(data_t* target, data_t* source, int length);
+
+/**
+ * The copy conversion function simply calls std::memcpy.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+template <class T>
+void convert_copy(data_t* target, data_t* source, int length)
+{
+ std::memcpy(target, source, length*sizeof(T));
+}
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_u8_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_u8_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s16_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s16_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 to FORMAT_S24 simply using std::memcpy.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s24(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s32_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s32_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_float_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_float_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_double_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_double_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_float(data_t* target, data_t* source, int length);
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ConverterReader.h b/extern/audaspace/include/respec/ConverterReader.h
new file mode 100644
index 00000000000..c5ff6ded9ad
--- /dev/null
+++ b/extern/audaspace/include/respec/ConverterReader.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ConverterReader.h
+ * @ingroup respec
+ * The ConverterReader class.
+ */
+
+#include "fx/EffectReader.h"
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class converts a sound source from one to another format.
+ */
+class AUD_API ConverterReader : public EffectReader
+{
+private:
+ /**
+ * The sound output buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The target specification.
+ */
+ SampleFormat m_format;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ // delete copy constructor and operator=
+ ConverterReader(const ConverterReader&) = delete;
+ ConverterReader& operator=(const ConverterReader&) = delete;
+
+public:
+ /**
+ * Creates a converter reader.
+ * \param reader The reader to convert.
+ * \param specs The target specification.
+ */
+ ConverterReader(std::shared_ptr<IReader> reader, DeviceSpecs specs);
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/JOSResample.h b/extern/audaspace/include/respec/JOSResample.h
new file mode 100644
index 00000000000..b1f4d757c3c
--- /dev/null
+++ b/extern/audaspace/include/respec/JOSResample.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file JOSResample.h
+ * @ingroup respec
+ * The JOSResample class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a resampling reader that does Julius O. Smith's resampling algorithm.
+ */
+class AUD_API JOSResample : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ JOSResample(const JOSResample&) = delete;
+ JOSResample& operator=(const JOSResample&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ JOSResample(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/JOSResampleReader.h b/extern/audaspace/include/respec/JOSResampleReader.h
new file mode 100644
index 00000000000..e9dd3b4220b
--- /dev/null
+++ b/extern/audaspace/include/respec/JOSResampleReader.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file JOSResampleReader.h
+ * @ingroup respec
+ * The JOSResampleReader class.
+ */
+
+#include "respec/ResampleReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This resampling reader uses Julius O. Smith's resampling algorithm.
+ */
+class AUD_API JOSResampleReader : public ResampleReader
+{
+private:
+ typedef void (JOSResampleReader::*resample_f)(double target_factor, int length, sample_t* buffer);
+
+ /**
+ * The half filter length.
+ */
+ static const int m_len;
+
+ /**
+ * The sample step size for the filter.
+ */
+ static const int m_L;
+
+ /**
+ * The filter coefficients.
+ */
+ static const float m_coeff[];
+
+ /**
+ * The reader channels.
+ */
+ Channels m_channels;
+
+ /**
+ * The sample position in the cache.
+ */
+ unsigned int m_n;
+
+ /**
+ * The subsample position in the cache.
+ */
+ double m_P;
+
+ /**
+ * The input data buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * Double buffer for the sums.
+ */
+ Buffer m_sums;
+
+ /**
+ * How many samples in the cache are valid.
+ */
+ int m_cache_valid;
+
+ /**
+ * Resample function.
+ */
+ resample_f m_resample;
+
+ /**
+ * Last resampling factor.
+ */
+ double m_last_factor;
+
+ // delete copy constructor and operator=
+ JOSResampleReader(const JOSResampleReader&) = delete;
+ JOSResampleReader& operator=(const JOSResampleReader&) = delete;
+
+ /**
+ * Resets the resampler to its initial state.
+ */
+ void AUD_LOCAL reset();
+
+ /**
+ * Updates the buffer to be as small as possible for the coming reading.
+ * \param size The size of samples to be read.
+ * \param factor The next resampling factor.
+ * \param samplesize The size of a sample.
+ */
+ void AUD_LOCAL updateBuffer(int size, double factor, int samplesize);
+
+ void AUD_LOCAL resample(double target_factor, int length, sample_t* buffer);
+ void AUD_LOCAL resample_mono(double target_factor, int length, sample_t* buffer);
+ void AUD_LOCAL resample_stereo(double target_factor, int length, sample_t* buffer);
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/LinearResample.h b/extern/audaspace/include/respec/LinearResample.h
new file mode 100644
index 00000000000..207cf2a6548
--- /dev/null
+++ b/extern/audaspace/include/respec/LinearResample.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LinearResample.h
+ * @ingroup respec
+ * The LinearResample class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a resampling reader that does simple linear resampling.
+ */
+class AUD_API LinearResample : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ LinearResample(const LinearResample&) = delete;
+ LinearResample& operator=(const LinearResample&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ LinearResample(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/LinearResampleReader.h b/extern/audaspace/include/respec/LinearResampleReader.h
new file mode 100644
index 00000000000..aaf95672e55
--- /dev/null
+++ b/extern/audaspace/include/respec/LinearResampleReader.h
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LinearResampleReader.h
+ * @ingroup respec
+ * The LinearResampleReader class.
+ */
+
+#include "respec/ResampleReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This resampling reader does simple first-order hold resampling.
+ */
+class AUD_API LinearResampleReader : public ResampleReader
+{
+private:
+ /**
+ * The reader channels.
+ */
+ Channels m_channels;
+
+ /**
+ * The position in the cache.
+ */
+ float m_cache_pos;
+
+ /**
+ * The sound output buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The input caching buffer.
+ */
+ Buffer m_cache;
+
+ /**
+ * Whether the cache contains valid data.
+ */
+ bool m_cache_ok;
+
+ // delete copy constructor and operator=
+ LinearResampleReader(const LinearResampleReader&) = delete;
+ LinearResampleReader& operator=(const LinearResampleReader&) = delete;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ LinearResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Mixer.h b/extern/audaspace/include/respec/Mixer.h
new file mode 100644
index 00000000000..600467826cd
--- /dev/null
+++ b/extern/audaspace/include/respec/Mixer.h
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Mixer.h
+ * @ingroup respec
+ * The Mixer class.
+ */
+
+#include "respec/Specification.h"
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * This abstract class is able to mix audiosignals with same channel count
+ * and sample rate and convert it to a specific output format.
+ */
+class AUD_API Mixer
+{
+private:
+ // delete copy constructor and operator=
+ Mixer(const Mixer&) = delete;
+ Mixer& operator=(const Mixer&) = delete;
+
+protected:
+ /**
+ * The output specification.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The length of the mixing buffer.
+ */
+ int m_length;
+
+ /**
+ * The mixing buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+public:
+ /**
+ * Creates the mixer.
+ */
+ Mixer(DeviceSpecs specs);
+
+ /**
+ * Destroys the mixer.
+ */
+ virtual ~Mixer() {}
+
+ /**
+ * Returns the target specification for superposing.
+ * \return The target specification.
+ */
+ DeviceSpecs getSpecs() const;
+
+ /**
+ * Sets the target specification for superposing.
+ * \param specs The target specification.
+ */
+ void setSpecs(Specs specs);
+
+ /**
+ * Mixes a buffer.
+ * \param buffer The buffer to superpose.
+ * \param start The start sample of the buffer.
+ * \param length The length of the buffer in samples.
+ * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void mix(sample_t* buffer, int start, int length, float volume);
+
+ /**
+ * Mixes a buffer with linear volume interpolation.
+ * \param buffer The buffer to superpose.
+ * \param start The start sample of the buffer.
+ * \param length The length of the buffer in samples.
+ * \param volume_to The target mixing volume. Must be a value between 0.0 and 1.0.
+ * \param volume_from The start mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void mix(sample_t* buffer, int start, int length, float volume_to, float volume_from);
+
+ /**
+ * Writes the mixing buffer into an output buffer.
+ * \param buffer The target buffer for superposing.
+ * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void read(data_t* buffer, float volume);
+
+ /**
+ * Clears the mixing buffer.
+ * \param length The length of the buffer in samples.
+ */
+ void clear(int length);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ResampleReader.h b/extern/audaspace/include/respec/ResampleReader.h
new file mode 100644
index 00000000000..b38a8d5eb18
--- /dev/null
+++ b/extern/audaspace/include/respec/ResampleReader.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ResampleReader.h
+ * @ingroup respec
+ * The ResampleReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This is the base class for all resampling readers.
+ */
+class AUD_API ResampleReader : public EffectReader
+{
+protected:
+ /**
+ * The target sampling rate.
+ */
+ SampleRate m_rate;
+
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ ResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+public:
+ /**
+ * Sets the sample rate.
+ * \param rate The target sampling rate.
+ */
+ virtual void setRate(SampleRate rate);
+
+ /**
+ * Retrieves the sample rate.
+ * \return The target sampling rate.
+ */
+ virtual SampleRate getRate();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Specification.h b/extern/audaspace/include/respec/Specification.h
new file mode 100644
index 00000000000..efcbb4cabce
--- /dev/null
+++ b/extern/audaspace/include/respec/Specification.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Specification.h
+ * @ingroup respec
+ * Defines all important macros and basic data structures for stream format descriptions.
+ */
+
+#include "Audaspace.h"
+
+/// The size of a format in bytes.
+#define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified device format in bytes.
+#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+/// The size of a sample in the specified format in bytes.
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
+
+/// Compares two audio data specifications.
+#define AUD_COMPARE_SPECS(s1, s2) ((s1.rate == s2.rate) && (s1.channels == s2.channels))
+
+/// Returns the bit for a channel mask.
+#define AUD_CHANNEL_BIT(channel) (0x01 << channel)
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The format of a sample.
+ * The last 4 bit save the byte count of the format.
+ */
+enum SampleFormat
+{
+ FORMAT_INVALID = 0x00, /// Invalid sample format.
+ FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
+ FORMAT_S16 = 0x12, /// 2 byte signed integer.
+ FORMAT_S24 = 0x13, /// 3 byte signed integer.
+ FORMAT_S32 = 0x14, /// 4 byte signed integer.
+ FORMAT_FLOAT32 = 0x24, /// 4 byte float.
+ FORMAT_FLOAT64 = 0x28 /// 8 byte float.
+};
+
+/// The channel count.
+enum Channels
+{
+ CHANNELS_INVALID = 0, /// Invalid channel count.
+ CHANNELS_MONO = 1, /// Mono.
+ CHANNELS_STEREO = 2, /// Stereo.
+ CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
+ CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
+ CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
+ CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
+ CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
+ CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
+};
+
+/// The channel names.
+enum Channel
+{
+ CHANNEL_FRONT_LEFT = 0,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT,
+ CHANNEL_REAR_CENTER,
+ CHANNEL_SIDE_LEFT,
+ CHANNEL_SIDE_RIGHT,
+ CHANNEL_MAX
+};
+
+/**
+ * The sample rate tells how many samples are played back within one second.
+ * Some exotic formats may use other sample rates than provided here.
+ */
+enum DefaultSampleRate
+{
+ RATE_INVALID = 0, /// Invalid sample rate.
+ RATE_8000 = 8000, /// 8000 Hz.
+ RATE_16000 = 16000, /// 16000 Hz.
+ RATE_11025 = 11025, /// 11025 Hz.
+ RATE_22050 = 22050, /// 22050 Hz.
+ RATE_32000 = 32000, /// 32000 Hz.
+ RATE_44100 = 44100, /// 44100 Hz.
+ RATE_48000 = 48000, /// 48000 Hz.
+ RATE_88200 = 88200, /// 88200 Hz.
+ RATE_96000 = 96000, /// 96000 Hz.
+ RATE_192000 = 192000 /// 192000 Hz.
+};
+
+/// Sample rate type.
+typedef double SampleRate;
+
+/// Specification of a sound source.
+struct Specs
+{
+ /// Sample rate in Hz.
+ SampleRate rate;
+
+ /// Channel count.
+ Channels channels;
+};
+
+/// Specification of a sound device.
+struct DeviceSpecs
+{
+ /// Sample format.
+ SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ SampleRate rate;
+
+ /// Channel count.
+ Channels channels;
+ };
+ Specs specs;
+ };
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/SpecsChanger.h b/extern/audaspace/include/respec/SpecsChanger.h
new file mode 100644
index 00000000000..2eb9f369497
--- /dev/null
+++ b/extern/audaspace/include/respec/SpecsChanger.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SpecsChanger.h
+ * @ingroup respec
+ * The SpecsChanger class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound is a base class for all mixer factories.
+ */
+class AUD_API SpecsChanger : public ISound
+{
+protected:
+ /**
+ * The target specification for resampling.
+ */
+ const DeviceSpecs m_specs;
+
+ /**
+ * If there is no reader it is created out of this sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * Returns the reader created out of the sound.
+ * This method can be used for the createReader function of the implementing
+ * classes.
+ * \return The reader to mix.
+ */
+ std::shared_ptr<IReader> getReader() const;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The sound to create the readers to mix out of.
+ * \param specs The target specification.
+ */
+ SpecsChanger(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ /**
+ * Returns the target specification for resampling.
+ */
+ DeviceSpecs getSpecs() const;
+
+ /**
+ * Returns the saved sound.
+ * \return The sound.
+ */
+ std::shared_ptr<ISound> getSound() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h
new file mode 100644
index 00000000000..2c3fcf23f8b
--- /dev/null
+++ b/extern/audaspace/include/sequence/AnimateableProperty.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file AnimateableProperty.h
+ * @ingroup sequence
+ * Defines the AnimateableProperty class as well as existing property types.
+ */
+
+#include "util/Buffer.h"
+#include "util/ILockable.h"
+
+#include <mutex>
+#include <list>
+
+AUD_NAMESPACE_BEGIN
+
+/// Possible animatable properties for Sequencer Factories and Entries.
+enum AnimateablePropertyType
+{
+ AP_VOLUME,
+ AP_PANNING,
+ AP_PITCH,
+ AP_LOCATION,
+ AP_ORIENTATION
+};
+
+/**
+ * This class saves animation data for float properties.
+ */
+class AUD_API AnimateableProperty : private Buffer
+{
+private:
+ struct Unknown {
+ int start;
+ int end;
+
+ Unknown(int start, int end) :
+ start(start), end(end) {}
+ };
+
+ /// The count of floats for a single property.
+ const int m_count;
+
+ /// Whether the property is animated or not.
+ bool m_isAnimated;
+
+ /// The mutex for locking.
+ std::recursive_mutex m_mutex;
+
+ /// The list of unknown buffer areas.
+ std::list<Unknown> m_unknown;
+
+ // delete copy constructor and operator=
+ AnimateableProperty(const AnimateableProperty&) = delete;
+ AnimateableProperty& operator=(const AnimateableProperty&) = delete;
+
+ void AUD_LOCAL updateUnknownCache(int start, int end);
+
+public:
+ /**
+ * Creates a new animateable property.
+ * \param count The count of floats for a single property.
+ */
+ AnimateableProperty(int count = 1);
+
+ /**
+ * Creates a new animateable property.
+ * \param count The count of floats for a single property.
+ * \param value The value that the property should get initialized with.
+ * All count floats will be initialized to the same value.
+ */
+ AnimateableProperty(int count, float value);
+
+ /**
+ * Destroys the animateable property.
+ */
+ ~AnimateableProperty();
+
+ /**
+ * Returns the count of floats for a single property.
+ * \return The count of floats stored per frame.
+ */
+ int getCount() const;
+
+ /**
+ * Writes the properties value and marks it non-animated.
+ * \param data The new value.
+ */
+ void write(const float* data);
+
+ /**
+ * Writes the properties value and marks it animated.
+ * \param data The new value.
+ * \param position The position in the animation in frames.
+ * \param count The count of frames to write.
+ */
+ void write(const float* data, int position, int count);
+
+ /**
+ * Reads the properties value.
+ * \param position The position in the animation in frames.
+ * \param[out] out Where to write the value to.
+ */
+ void read(float position, float* out);
+
+ /**
+ * Returns whether the property is animated.
+ * \return Whether the property is animated.
+ */
+ bool isAnimated() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/Double.h b/extern/audaspace/include/sequence/Double.h
new file mode 100644
index 00000000000..dc40ae29e0d
--- /dev/null
+++ b/extern/audaspace/include/sequence/Double.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Double.h
+ * @ingroup sequence
+ * The Double class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays two other factories behind each other.
+ */
+class AUD_API Double : public ISound
+{
+private:
+ /**
+ * First played sound.
+ */
+ std::shared_ptr<ISound> m_sound1;
+
+ /**
+ * Second played sound.
+ */
+ std::shared_ptr<ISound> m_sound2;
+
+ // delete copy constructor and operator=
+ Double(const Double&) = delete;
+ Double& operator=(const Double&) = delete;
+
+public:
+ /**
+ * Creates a new double sound.
+ * \param sound1 The first input sound.
+ * \param sound2 The second input sound.
+ */
+ Double(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/DoubleReader.h b/extern/audaspace/include/sequence/DoubleReader.h
new file mode 100644
index 00000000000..012dcc8e832
--- /dev/null
+++ b/extern/audaspace/include/sequence/DoubleReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DoubleReader.h
+ * @ingroup sequence
+ * The DoubleReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader plays two readers sequently.
+ */
+class AUD_API DoubleReader : public IReader
+{
+private:
+ /**
+ * The first reader.
+ */
+ std::shared_ptr<IReader> m_reader1;
+
+ /**
+ * The second reader.
+ */
+ std::shared_ptr<IReader> m_reader2;
+
+ /**
+ * Whether we've reached the end of the first reader.
+ */
+ bool m_finished1;
+
+ // delete copy constructor and operator=
+ DoubleReader(const DoubleReader&) = delete;
+ DoubleReader& operator=(const DoubleReader&) = delete;
+
+public:
+ /**
+ * Creates a new double reader.
+ * \param reader1 The first reader to read from.
+ * \param reader2 The second reader to read from.
+ */
+ DoubleReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~DoubleReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/PingPong.h b/extern/audaspace/include/sequence/PingPong.h
new file mode 100644
index 00000000000..8b1bf792095
--- /dev/null
+++ b/extern/audaspace/include/sequence/PingPong.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PingPong.h
+ * @ingroup sequence
+ * The PingPong class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays another sound first normal, then reversed.
+ * \note Readers from the underlying sound must be reversable with seeking.
+ */
+class AUD_API PingPong : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ PingPong(const PingPong&) = delete;
+ PingPong& operator=(const PingPong&) = delete;
+
+public:
+ /**
+ * Creates a new ping pong sound.
+ * \param sound The input sound.
+ */
+ PingPong(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/extern/audaspace/include/sequence/Sequence.h
index 3ef847d4b34..7005171e2c8 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/extern/audaspace/include/sequence/Sequence.h
@@ -1,58 +1,52 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SequencerFactory.h
- * \ingroup audaspaceintern
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+#pragma once
-#ifndef __AUD_SEQUENCERFACTORY_H__
-#define __AUD_SEQUENCERFACTORY_H__
+/**
+ * @file Sequence.h
+ * @ingroup sequence
+ * The Sequence class.
+ */
-#include "AUD_IFactory.h"
-#include "AUD_AnimateableProperty.h"
-//#include "AUD_ILockable.h"
-#include "AUD_Sequencer.h"
+#include "ISound.h"
+#include "respec/Specification.h"
+#include "devices/I3DDevice.h"
+#include "sequence/AnimateableProperty.h"
#include <list>
-#include <pthread.h>
-class AUD_SequencerEntry;
+AUD_NAMESPACE_BEGIN
+
+class SequenceEntry;
+class SequenceData;
/**
- * This factory represents sequenced entries to play a sound scene.
+ * This sound represents sequenced entries to play a sound scene.
*/
-class AUD_SequencerFactory : public AUD_IFactory//, public AUD_ILockable
+class AUD_API Sequence : public ISound
{
- friend class AUD_SequencerReader;
+ friend class SequenceReader;
private:
/// The sequence.
- boost::shared_ptr<AUD_Sequencer> m_sequence;
+ std::shared_ptr<SequenceData> m_sequence;
- // hide copy constructor and operator=
- AUD_SequencerFactory(const AUD_SequencerFactory&);
- AUD_SequencerFactory& operator=(const AUD_SequencerFactory&);
+ // delete copy constructor and operator=
+ Sequence(const Sequence&) = delete;
+ Sequence& operator=(const Sequence&) = delete;
public:
/**
@@ -61,25 +55,25 @@ public:
* \param fps The FPS of the scene.
* \param muted Whether the whole scene is muted.
*/
- AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted);
+ Sequence(Specs specs, float fps, bool muted);
-#if 0
/**
- * Locks the factory.
+ * Retrieves the audio output specification.
+ * \return The specification.
*/
- virtual void lock();
+ Specs getSpecs();
/**
- * Unlocks the previously locked factory.
+ * Sets the audio output specification.
+ * \param specs The new specification.
*/
- virtual void unlock();
-#endif
+ void setSpecs(Specs specs);
/**
- * Sets the audio output specification.
- * \param specs The new specification.
+ * Retrieves the scene's FPS.
+ * \return The scene's FPS.
*/
- void setSpecs(AUD_Specs specs);
+ float getFPS() const;
/**
* Sets the scene's FPS.
@@ -97,7 +91,7 @@ public:
* Retrieves the muting state of the scene.
* \return Whether the scene is muted.
*/
- bool getMute() const;
+ bool isMuted() const;
/**
* Retrieves the speed of sound.
@@ -133,21 +127,21 @@ public:
* Retrieves the distance model.
* \return The distance model.
*/
- AUD_DistanceModel getDistanceModel() const;
+ DistanceModel getDistanceModel() const;
/**
* Sets the distance model.
* \param model distance model.
*/
- void setDistanceModel(AUD_DistanceModel model);
+ void setDistanceModel(DistanceModel model);
/**
- * Retrieves one of the animated properties of the factory.
+ * Retrieves one of the animated properties of the sound.
* \param type Which animated property to retrieve.
* \return A pointer to the animated property, valid as long as the
- * factory is.
+ * sound is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Adds a new entry to the scene.
@@ -157,21 +151,21 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \return The entry added.
*/
- boost::shared_ptr<AUD_SequencerEntry> add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip);
+ std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> sound, float begin, float end, float skip);
/**
* Removes an entry from the scene.
* \param entry The entry to remove.
*/
- void remove(boost::shared_ptr<AUD_SequencerEntry> entry);
+ void remove(std::shared_ptr<SequenceEntry> entry);
/**
* Creates a new reader with high quality resampling.
* \return The new reader.
*/
- boost::shared_ptr<AUD_IReader> createQualityReader();
+ std::shared_ptr<IReader> createQualityReader();
- virtual boost::shared_ptr<AUD_IReader> createReader();
+ virtual std::shared_ptr<IReader> createReader();
};
-#endif //__AUD_SEQUENCERFACTORY_H__
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_Sequencer.h b/extern/audaspace/include/sequence/SequenceData.h
index 1066eeae8e3..b3df0548a4d 100644
--- a/intern/audaspace/intern/AUD_Sequencer.h
+++ b/extern/audaspace/include/sequence/SequenceData.h
@@ -1,53 +1,50 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Sequencer.h
- * \ingroup audaspaceintern
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+#pragma once
-#ifndef __AUD_SEQUENCER_H__
-#define __AUD_SEQUENCER_H__
+/**
+ * @file SequenceData.h
+ * @ingroup sequence
+ * The SequenceData class.
+ */
-#include "AUD_AnimateableProperty.h"
-#include "AUD_IFactory.h"
-#include "AUD_ILockable.h"
+#include "respec/Specification.h"
+#include "sequence/AnimateableProperty.h"
+#include "devices/I3DDevice.h"
+#include "util/ILockable.h"
#include <list>
-#include <pthread.h>
+#include <memory>
+#include <mutex>
-class AUD_SequencerEntry;
+AUD_NAMESPACE_BEGIN
+
+class SequenceEntry;
+class ISound;
/**
* This class represents sequenced entries to play a sound scene.
*/
-class AUD_Sequencer : public AUD_ILockable
+class AUD_API SequenceData : public ILockable
{
- friend class AUD_SequencerReader;
+ friend class SequenceReader;
private:
/// The target specification.
- AUD_Specs m_specs;
+ Specs m_specs;
/// The status of the sequence. Changes every time a non-animated parameter changes.
int m_status;
@@ -59,7 +56,7 @@ private:
int m_id;
/// The sequenced entries.
- std::list<boost::shared_ptr<AUD_SequencerEntry> > m_entries;
+ std::list<std::shared_ptr<SequenceEntry> > m_entries;
/// Whether the whole scene is muted.
bool m_muted;
@@ -74,23 +71,23 @@ private:
float m_doppler_factor;
/// Distance model.
- AUD_DistanceModel m_distance_model;
+ DistanceModel m_distance_model;
/// The animated volume.
- AUD_AnimateableProperty m_volume;
+ AnimateableProperty m_volume;
/// The animated listener location.
- AUD_AnimateableProperty m_location;
+ AnimateableProperty m_location;
/// The animated listener orientation.
- AUD_AnimateableProperty m_orientation;
+ AnimateableProperty m_orientation;
/// The mutex for locking.
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
- // hide copy constructor and operator=
- AUD_Sequencer(const AUD_Sequencer&);
- AUD_Sequencer& operator=(const AUD_Sequencer&);
+ // delete copy constructor and operator=
+ SequenceData(const SequenceData&) = delete;
+ SequenceData& operator=(const SequenceData&) = delete;
public:
/**
@@ -99,8 +96,8 @@ public:
* \param fps The FPS of the scene.
* \param muted Whether the whole scene is muted.
*/
- AUD_Sequencer(AUD_Specs specs, float fps, bool muted);
- virtual ~AUD_Sequencer();
+ SequenceData(Specs specs, float fps, bool muted);
+ virtual ~SequenceData();
/**
* Locks the sequence.
@@ -113,10 +110,22 @@ public:
virtual void unlock();
/**
+ * Retrieves the audio output specification.
+ * \return The specification.
+ */
+ Specs getSpecs();
+
+ /**
* Sets the audio output specification.
* \param specs The new specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(Specs specs);
+
+ /**
+ * Retrieves the scene's FPS.
+ * \return The scene's FPS.
+ */
+ float getFPS() const;
/**
* Sets the scene's FPS.
@@ -134,7 +143,7 @@ public:
* Retrieves the muting state of the scene.
* \return Whether the scene is muted.
*/
- bool getMute() const;
+ bool isMuted() const;
/**
* Retrieves the speed of sound.
@@ -170,13 +179,13 @@ public:
* Retrieves the distance model.
* \return The distance model.
*/
- AUD_DistanceModel getDistanceModel() const;
+ DistanceModel getDistanceModel() const;
/**
* Sets the distance model.
* \param model distance model.
*/
- void setDistanceModel(AUD_DistanceModel model);
+ void setDistanceModel(DistanceModel model);
/**
* Retrieves one of the animated properties of the sequence.
@@ -184,7 +193,7 @@ public:
* \return A pointer to the animated property, valid as long as the
* sequence is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Adds a new entry to the scene.
@@ -194,13 +203,13 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \return The entry added.
*/
- boost::shared_ptr<AUD_SequencerEntry> add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip);
+ std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> sound, float begin, float end, float skip);
/**
* Removes an entry from the scene.
* \param entry The entry to remove.
*/
- void remove(boost::shared_ptr<AUD_SequencerEntry> entry);
+ void remove(std::shared_ptr<SequenceEntry> entry);
};
-#endif //__AUD_SEQUENCER_H__
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h
index aa1edebfc2f..98f15faf7ff 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.h
+++ b/extern/audaspace/include/sequence/SequenceEntry.h
@@ -1,48 +1,43 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerEntry.h
- * \ingroup audaspaceintern
+#pragma once
+
+/**
+ * @file SequenceEntry.h
+ * @ingroup sequence
+ * The SequenceEntry class.
*/
+#include "sequence/AnimateableProperty.h"
+#include "util/ILockable.h"
-#ifndef __AUD_SEQUENCERENTRY_H__
-#define __AUD_SEQUENCERENTRY_H__
+#include <mutex>
+#include <memory>
-#include "AUD_AnimateableProperty.h"
-#include "AUD_IFactory.h"
-#include "AUD_ILockable.h"
+AUD_NAMESPACE_BEGIN
-#include <pthread.h>
-#include <boost/shared_ptr.hpp>
+class ISound;
/**
- * This class represents a sequenced entry in a sequencer factory.
+ * This class represents a sequenced entry in a sequencer sound.
*/
-class AUD_SequencerEntry : public AUD_ILockable
+class AUD_API SequenceEntry : public ILockable
{
- friend class AUD_SequencerHandle;
+ friend class SequenceHandle;
private:
/// The status of the entry. Changes every time a non-animated parameter changes.
int m_status;
@@ -53,11 +48,11 @@ private:
/// The sound status, changed when the sound is changed.
int m_sound_status;
- /// The unique (regarding the factory) ID of the entry.
+ /// The unique (regarding the sound) ID of the entry.
int m_id;
/// The sound this entry plays.
- boost::shared_ptr<AUD_IFactory> m_sound;
+ std::shared_ptr<ISound> m_sound;
/// The begin time.
float m_begin;
@@ -99,22 +94,26 @@ private:
float m_cone_volume_outer;
/// The mutex for locking.
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/// The animated volume.
- AUD_AnimateableProperty m_volume;
+ AnimateableProperty m_volume;
/// The animated panning.
- AUD_AnimateableProperty m_panning;
+ AnimateableProperty m_panning;
/// The animated pitch.
- AUD_AnimateableProperty m_pitch;
+ AnimateableProperty m_pitch;
/// The animated location.
- AUD_AnimateableProperty m_location;
+ AnimateableProperty m_location;
/// The animated orientation.
- AUD_AnimateableProperty m_orientation;
+ AnimateableProperty m_orientation;
+
+ // delete copy constructor and operator=
+ SequenceEntry(const SequenceEntry&) = delete;
+ SequenceEntry& operator=(const SequenceEntry&) = delete;
public:
/**
@@ -125,8 +124,8 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \param id The ID of the entry.
*/
- AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip, int id);
- virtual ~AUD_SequencerEntry();
+ SequenceEntry(std::shared_ptr<ISound> sound, float begin, float end, float skip, int id);
+ virtual ~SequenceEntry();
/**
* Locks the entry.
@@ -139,10 +138,16 @@ public:
virtual void unlock();
/**
+ * Retrieves the sound of the entry.
+ * \return The sound.
+ */
+ std::shared_ptr<ISound> getSound();
+
+ /**
* Sets the sound of the entry.
* \param sound The new sound.
*/
- void setSound(boost::shared_ptr<AUD_IFactory> sound);
+ void setSound(std::shared_ptr<ISound> sound);
/**
* Moves the entry.
@@ -153,6 +158,12 @@ public:
void move(float begin, float end, float skip);
/**
+ * Retrieves the muting state of the entry.
+ * \return Whether the entry should is muted or not.
+ */
+ bool isMuted();
+
+ /**
* Sets the muting state of the entry.
* \param mute Whether the entry should be muted or not.
*/
@@ -170,22 +181,7 @@ public:
* \return A pointer to the animated property, valid as long as the
* entry is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
-
- /**
- * Updates all non-animated parameters of the entry.
- * \param volume_max The maximum volume.
- * \param volume_min The minimum volume.
- * \param distance_max The maximum distance.
- * \param distance_reference The reference distance.
- * \param attenuation The attenuation.
- * \param cone_angle_outer The outer cone opening angle.
- * \param cone_angle_inner The inner cone opening angle.
- * \param cone_volume_outer The volume outside the outer cone.
- */
- void updateAll(float volume_max, float volume_min, float distance_max,
- float distance_reference, float attenuation, float cone_angle_outer,
- float cone_angle_inner, float cone_volume_outer);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Checks whether the source location, velocity and orientation are relative
@@ -316,4 +312,4 @@ public:
void setConeVolumeOuter(float volume);
};
-#endif //__AUD_SEQUENCERENTRY_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/SequenceReader.h b/extern/audaspace/include/sequence/SequenceReader.h
new file mode 100644
index 00000000000..196d969e102
--- /dev/null
+++ b/extern/audaspace/include/sequence/SequenceReader.h
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SequenceReader.h
+ * @ingroup sequence
+ * The SequenceReader class.
+ */
+
+#include "IReader.h"
+#include "devices/ReadDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+class SequenceHandle;
+class SequenceData;
+
+/**
+ * This reader plays back sequenced entries.
+ */
+class AUD_API SequenceReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The read device used to mix the sounds correctly.
+ */
+ ReadDevice m_device;
+
+ /**
+ * Saves the sequence the reader belongs to.
+ */
+ std::shared_ptr<SequenceData> m_sequence;
+
+ /**
+ * The list of playback handles for the entries.
+ */
+ std::list<std::shared_ptr<SequenceHandle> > m_handles;
+
+ /**
+ * Last status read from the sequence.
+ */
+ int m_status;
+
+ /**
+ * Last entry status read from the sequence.
+ */
+ int m_entry_status;
+
+ // delete copy constructor and operator=
+ SequenceReader(const SequenceReader&) = delete;
+ SequenceReader& operator=(const SequenceReader&) = delete;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param sequence The sequence data.
+ * \param quality Whether a high quality resample should be used for resampling.
+ */
+ SequenceReader(std::shared_ptr<SequenceData> sequence, bool quality = false);
+
+ /**
+ * Destroys the reader.
+ */
+ ~SequenceReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/Superpose.h b/extern/audaspace/include/sequence/Superpose.h
new file mode 100644
index 00000000000..2a3a6166b3b
--- /dev/null
+++ b/extern/audaspace/include/sequence/Superpose.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Superpose.h
+ * @ingroup sequence
+ * The Superpose class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound mixes two other factories, playing them the same time.
+ * \note Readers from the underlying factories must have the same sample rate
+ * and channel count.
+ */
+class AUD_API Superpose : public ISound
+{
+private:
+ /**
+ * First played sound.
+ */
+ std::shared_ptr<ISound> m_sound1;
+
+ /**
+ * Second played sound.
+ */
+ std::shared_ptr<ISound> m_sound2;
+
+ // delete copy constructor and operator=
+ Superpose(const Superpose&) = delete;
+ Superpose& operator=(const Superpose&) = delete;
+
+public:
+ /**
+ * Creates a new superpose sound.
+ * \param sound1 The first input sound.
+ * \param sound2 The second input sound.
+ */
+ Superpose(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/SuperposeReader.h b/extern/audaspace/include/sequence/SuperposeReader.h
new file mode 100644
index 00000000000..8bd38ade4c3
--- /dev/null
+++ b/extern/audaspace/include/sequence/SuperposeReader.h
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SuperposeReader.h
+ * @ingroup sequence
+ * The SuperposeReader class.
+ */
+
+#include "IReader.h"
+#include "util/Buffer.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader plays two readers with the same specs in parallel.
+ */
+class AUD_API SuperposeReader : public IReader
+{
+private:
+ /**
+ * The first reader.
+ */
+ std::shared_ptr<IReader> m_reader1;
+
+ /**
+ * The second reader.
+ */
+ std::shared_ptr<IReader> m_reader2;
+
+ /**
+ * Buffer used for mixing.
+ */
+ Buffer m_buffer;
+
+ // delete copy constructor and operator=
+ SuperposeReader(const SuperposeReader&) = delete;
+ SuperposeReader& operator=(const SuperposeReader&) = delete;
+
+public:
+ /**
+ * Creates a new superpose reader.
+ * \param reader1 The first reader to read from.
+ * \param reader2 The second reader to read from.
+ * \exception Exception Thrown if the specs from the readers differ.
+ */
+ SuperposeReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~SuperposeReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/Barrier.h b/extern/audaspace/include/util/Barrier.h
new file mode 100644
index 00000000000..d9e8bf07f82
--- /dev/null
+++ b/extern/audaspace/include/util/Barrier.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Barrier.h
+* @ingroup util
+* The Barrier class.
+*/
+
+#include "Audaspace.h"
+
+#include <mutex>
+#include <condition_variable>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This represents a barrier mechanism for thread sychronization.
+*/
+class Barrier
+{
+private:
+ /**
+ * A mutex needed to use a condition variable.
+ */
+ std::mutex m_mutex;
+
+ /**
+ * Condition varieble used to sync threads.
+ */
+ std::condition_variable m_condition;
+
+ /**
+ * Number of threads that need to reach the barrier for it to lift.
+ */
+ unsigned int m_threshold;
+
+ /**
+ * Conter that count from threshold to 0.
+ */
+ unsigned int m_count;
+
+ /**
+ * Variable used for predicate check in the condition variable wait.
+ */
+ unsigned int m_generation;
+
+ // delete copy constructor and operator=
+ Barrier(const Barrier&) = delete;
+ Barrier& operator=(const Barrier&) = delete;
+public:
+ /**
+ * Creates a new Barrier object.
+ * \param count the number of threads that need to reach the barrier for it to lift.
+ */
+ Barrier(unsigned int count);
+ virtual ~Barrier();
+
+ /**
+ * Makes the caller thread wait until enough threads are stopped by this method.
+ */
+ void wait();
+};
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/util/Buffer.h b/extern/audaspace/include/util/Buffer.h
new file mode 100644
index 00000000000..9934e53625e
--- /dev/null
+++ b/extern/audaspace/include/util/Buffer.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Buffer.h
+ * @ingroup util
+ * The Buffer class.
+ */
+
+#include "Audaspace.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is a simple buffer in RAM which is 32 Byte aligned and provides
+ * resize functionality.
+ */
+class AUD_API Buffer
+{
+private:
+ /// The size of the buffer in bytes.
+ int m_size;
+
+ /// The pointer to the buffer memory.
+ data_t* m_buffer;
+
+ // delete copy constructor and operator=
+ Buffer(const Buffer&) = delete;
+ Buffer& operator=(const Buffer&) = delete;
+
+public:
+ /**
+ * Creates a new buffer.
+ * \param size The size of the buffer in bytes.
+ */
+ Buffer(int size = 0);
+
+ /**
+ * Destroys the buffer.
+ */
+ ~Buffer();
+
+ /**
+ * Returns the pointer to the buffer in memory.
+ */
+ sample_t* getBuffer() const;
+
+ /**
+ * Returns the size of the buffer in bytes.
+ */
+ int getSize() const;
+
+ /**
+ * Resizes the buffer.
+ * \param size The new size of the buffer, measured in bytes.
+ * \param keep Whether to keep the old data. If the new buffer is smaller,
+ * the data at the end will be lost.
+ */
+ void resize(int size, bool keep = false);
+
+ /**
+ * Makes sure the buffer has a minimum size.
+ * If size is >= current size, nothing will happen.
+ * Otherwise the buffer is resized with keep as parameter.
+ * \param size The new minimum size of the buffer, measured in bytes.
+ * \param keep Whether to keep the old data. If the new buffer is smaller,
+ * the data at the end will be lost.
+ */
+ void assureSize(int size, bool keep = false);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/BufferReader.h b/extern/audaspace/include/util/BufferReader.h
new file mode 100644
index 00000000000..b98313726bc
--- /dev/null
+++ b/extern/audaspace/include/util/BufferReader.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file BufferReader.h
+ * @ingroup util
+ * The BufferReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This class represents a simple reader from a buffer that exists in memory.
+ * \warning Notice that the buffer is not multi-threading ready, so changing the
+ * buffer while the reader is reading is potentially dangerous.
+ */
+class AUD_API BufferReader : public IReader
+{
+private:
+ /**
+ * The current position in the buffer.
+ */
+ int m_position;
+
+ /**
+ * The buffer that is read.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ /**
+ * The specification of the sample data in the buffer.
+ */
+ Specs m_specs;
+
+ // delete copy constructor and operator=
+ BufferReader(const BufferReader&) = delete;
+ BufferReader& operator=(const BufferReader&) = delete;
+
+public:
+ /**
+ * Creates a new buffer reader.
+ * \param buffer The buffer to read from.
+ * \param specs The specification of the sample data in the buffer.
+ */
+ BufferReader(std::shared_ptr<Buffer> buffer, Specs specs);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/FFTPlan.h b/extern/audaspace/include/util/FFTPlan.h
new file mode 100644
index 00000000000..7d533ca8773
--- /dev/null
+++ b/extern/audaspace/include/util/FFTPlan.h
@@ -0,0 +1,120 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file FFTPlan.h
+* @ingroup util
+* The FFTPlan class.
+*/
+
+#include <complex>
+#include <fftw3.h>
+#include "Audaspace.h"
+
+#include <memory>
+#include <vector>
+
+/**Default FFT size.*/
+#define DEFAULT_N 4096
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* Thas class represents an plan object that allows to calculate FFTs and IFFTs.
+*/
+class AUD_API FFTPlan
+{
+private:
+ /**
+ * The size of the FFT plan.
+ */
+ int m_N;
+
+ /**
+ * The plan to transform the input to the frequency domain.
+ */
+ fftwf_plan m_fftPlanR2C;
+
+ /**
+ * The plan to transform the input to the time domain again.
+ */
+ fftwf_plan m_fftPlanC2R;
+
+ /**
+ * The size of a buffer for its use with the FFT plan (in bytes).
+ */
+ unsigned int m_bufferSize;
+
+ // delete copy constructor and operator=
+ FFTPlan(const FFTPlan&) = delete;
+ FFTPlan& operator=(const FFTPlan&) = delete;
+
+public:
+ /**
+ * Creates a new FFTPlan object with DEFAULT_N size (4096).
+ * \param measureTime The aproximate amount of seconds that FFTW will spend searching for the optimal plan,
+ * which means faster FFTs and IFFTs while using this plan. If measureTime is negative, it will take all the time it needs.
+ */
+ FFTPlan(double measureTime = 0);
+
+ /**
+ * Creates a new FFTPlan object with a custom size.
+ * \param n The size of the FFT plan. Values that are a power of two are faster.
+ * The useful range usually is between 2048 and 8192, but bigger values can be useful
+ * in certain situations (when using the StreamBuffer class per example).
+ * Generally, low values use more CPU power and are a bit faster than large ones,
+ * there is also a huge decrease in efficiency when n is lower than 2048.
+ * \param measureTime The aproximate amount of seconds that FFTW will spend searching for the optimal plan,
+ * which means faster FFTs while using this plan. If measureTime is negative, it will take all the time it needs.
+ */
+ FFTPlan(int n, double measureTime = 0);
+ ~FFTPlan();
+
+ /**
+ * Retrieves the size of the FFT plan.
+ * \return The size of the plan.
+ */
+ int getSize();
+
+ /**
+ * Calculates the FFT of an input buffer with the current plan.
+ * \param[in,out] buffer A buffer with the input data an in which the output data will be written.
+ */
+ void FFT(void* buffer);
+
+ /**
+ * Calculates the IFFT of an input buffer with the current plan.
+ * \param[in,out] buffer A buffer with the input data an in which the output data will be written.
+ */
+ void IFFT(void* buffer);
+
+ /**
+ * Reserves memory for a buffer that can be used for inplace transformations with this plan.
+ * \return A pointer to a buffer of size ((N/2)+1)*2*sizeof(fftwf_complex).
+ * \warning The returned buffer must be freed with the freeBuffer method of this class.
+ */
+ void* getBuffer();
+
+ /**
+ * Frees one of the buffers reserved with the getRealOnlyBuffer(), getComplexOnlyBuffer() or getInplaceBuffer() method.
+ * \param buffer A pointer to the buufer taht must be freed.
+ */
+ void freeBuffer(void* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/ILockable.h b/extern/audaspace/include/util/ILockable.h
new file mode 100644
index 00000000000..8300fbd2845
--- /dev/null
+++ b/extern/audaspace/include/util/ILockable.h
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ILockable.h
+ * @ingroup util
+ * The ILockable interface.
+ */
+
+#include "Audaspace.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface ILockable
+ * This class provides an interface for lockable objects.
+ */
+class AUD_API ILockable
+{
+public:
+ /**
+ * Locks the object.
+ */
+ virtual void lock()=0;
+ /**
+ * Unlocks the previously locked object.
+ */
+ virtual void unlock()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_3DMath.h b/extern/audaspace/include/util/Math3D.h
index 1b109ebee1e..7ded12c1ba8 100644
--- a/intern/audaspace/intern/AUD_3DMath.h
+++ b/extern/audaspace/include/util/Math3D.h
@@ -1,42 +1,38 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_3DMath.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file Math3D.h
+ * @ingroup util
+ * Defines the Vector3 and Quaternion classes.
+ */
-#ifndef __AUD_3DMATH_H__
-#define __AUD_3DMATH_H__
+#include "Audaspace.h"
#include <cmath>
#include <cstring>
+AUD_NAMESPACE_BEGIN
+
/**
* This class represents a 3 dimensional vector.
*/
-class AUD_Vector3
+class AUD_API Vector3
{
private:
/**
@@ -60,7 +56,7 @@ public:
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Vector3(float x = 0, float y = 0, float z = 0) :
+ inline Vector3(float x = 0, float y = 0, float z = 0) :
m_x(x), m_y(y), m_z(z)
{
}
@@ -98,7 +94,7 @@ public:
*/
inline void get(float* destination) const
{
- memcpy(destination, m_v, sizeof(m_v));
+ std::memcpy(destination, m_v, sizeof(m_v));
}
/**
@@ -125,7 +121,7 @@ public:
*/
inline float length() const
{
- return sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
+ return std::sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
}
/**
@@ -133,11 +129,11 @@ public:
* \param op The second operand.
* \return The cross product of the two vectors.
*/
- inline AUD_Vector3 cross(const AUD_Vector3& op) const
+ inline Vector3 cross(const Vector3& op) const
{
- return AUD_Vector3(m_y * op.m_z - m_z * op.m_y,
- m_z * op.m_x - m_x * op.m_z,
- m_x * op.m_y - m_y * op.m_x);
+ return Vector3(m_y * op.m_z - m_z * op.m_y,
+ m_z * op.m_x - m_x * op.m_z,
+ m_x * op.m_y - m_y * op.m_x);
}
/**
@@ -145,7 +141,7 @@ public:
* \param op The second operand.
* \return The dot product of the two vectors.
*/
- inline float operator*(const AUD_Vector3& op) const
+ inline float operator*(const Vector3& op) const
{
return m_x * op.m_x + m_y * op.m_y + m_z * op.m_z;
}
@@ -155,9 +151,9 @@ public:
* \param op The second operand.
* \return The scaled vector.
*/
- inline AUD_Vector3 operator*(const float& op) const
+ inline Vector3 operator*(const float& op) const
{
- return AUD_Vector3(m_x * op, m_y * op, m_z * op);
+ return Vector3(m_x * op, m_y * op, m_z * op);
}
/**
@@ -165,9 +161,9 @@ public:
* \param op The second operand.
* \return The sum vector.
*/
- inline AUD_Vector3 operator+(const AUD_Vector3& op) const
+ inline Vector3 operator+(const Vector3& op) const
{
- return AUD_Vector3(m_x + op.m_x, m_y + op.m_y, m_z + op.m_z);
+ return Vector3(m_x + op.m_x, m_y + op.m_y, m_z + op.m_z);
}
/**
@@ -175,18 +171,18 @@ public:
* \param op The second operand.
* \return The difference vector.
*/
- inline AUD_Vector3 operator-(const AUD_Vector3& op) const
+ inline Vector3 operator-(const Vector3& op) const
{
- return AUD_Vector3(m_x - op.m_x, m_y - op.m_y, m_z - op.m_z);
+ return Vector3(m_x - op.m_x, m_y - op.m_y, m_z - op.m_z);
}
/**
* Negates the vector.
* \return The vector facing in the opposite direction.
*/
- inline AUD_Vector3 operator-() const
+ inline Vector3 operator-() const
{
- return AUD_Vector3(-m_x, -m_y, -m_z);
+ return Vector3(-m_x, -m_y, -m_z);
}
/**
@@ -194,7 +190,7 @@ public:
* \param op The second operand.
* \return The difference vector.
*/
- inline AUD_Vector3& operator-=(const AUD_Vector3& op)
+ inline Vector3& operator-=(const Vector3& op)
{
m_x -= op.m_x;
m_y -= op.m_y;
@@ -206,7 +202,7 @@ public:
/**
* This class represents a quaternion used for 3D rotations.
*/
-class AUD_Quaternion
+class AUD_API Quaternion
{
private:
/**
@@ -232,7 +228,7 @@ public:
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Quaternion(float w = 1, float x = 0, float y = 0, float z = 0) :
+ inline Quaternion(float w = 1, float x = 0, float y = 0, float z = 0) :
m_w(w), m_x(x), m_y(y), m_z(z)
{
}
@@ -279,7 +275,7 @@ public:
*/
inline void get(float* destination) const
{
- memcpy(destination, m_v, sizeof(m_v));
+ std::memcpy(destination, m_v, sizeof(m_v));
}
/**
@@ -305,11 +301,11 @@ public:
* z axis vector.
* \return The negative z axis vector.
*/
- inline AUD_Vector3 getLookAt() const
+ inline Vector3 getLookAt() const
{
- return AUD_Vector3(-2 * (m_w * m_y + m_x * m_z),
- 2 * (m_x * m_w - m_z * m_y),
- 2 * (m_x * m_x + m_y * m_y) - 1);
+ return Vector3(-2 * (m_w * m_y + m_x * m_z),
+ 2 * (m_x * m_w - m_z * m_y),
+ 2 * (m_x * m_x + m_y * m_y) - 1);
}
/**
@@ -317,12 +313,12 @@ public:
* vector.
* \return The y axis vector.
*/
- inline AUD_Vector3 getUp() const
+ inline Vector3 getUp() const
{
- return AUD_Vector3(2 * (m_x * m_y - m_w * m_z),
+ return Vector3(2 * (m_x * m_y - m_w * m_z),
1 - 2 * (m_x * m_x + m_z * m_z),
2 * (m_w * m_x + m_y * m_z));
}
};
-#endif //__AUD_3DMATH_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/StreamBuffer.h b/extern/audaspace/include/util/StreamBuffer.h
new file mode 100644
index 00000000000..8ec4cfcf46d
--- /dev/null
+++ b/extern/audaspace/include/util/StreamBuffer.h
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file StreamBuffer.h
+ * @ingroup util
+ * The StreamBuffer class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This sound creates a buffer out of a reader. This way normally streamed
+ * sound sources can be loaded into memory for buffered playback.
+ */
+class AUD_API StreamBuffer : public ISound
+{
+private:
+ /**
+ * The buffer that holds the audio data.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ /**
+ * The specification of the samples.
+ */
+ Specs m_specs;
+
+ // delete copy constructor and operator=
+ StreamBuffer(const StreamBuffer&) = delete;
+ StreamBuffer& operator=(const StreamBuffer&) = delete;
+
+public:
+ /**
+ * Creates the sound and reads the reader created by the sound supplied
+ * to the buffer.
+ * \param sound The sound that creates the reader for buffering.
+ * \exception Exception Thrown if the reader cannot be created.
+ */
+ StreamBuffer(std::shared_ptr<ISound> sound);
+
+ /**
+ * Creates the sound from an preexisting buffer.
+ * \param buffer The buffer to stream from.
+ * \param specs The specification of the data in the buffer.
+ * \exception Exception Thrown if the reader cannot be created.
+ */
+ StreamBuffer(std::shared_ptr<Buffer> buffer, Specs specs);
+
+ /**
+ * Returns the buffer to be streamed.
+ * @return The buffer to stream.
+ */
+ std::shared_ptr<Buffer> getBuffer();
+
+ /**
+ * Returns the specification of the buffer.
+ * @return The specification of the buffer.
+ */
+ Specs getSpecs();
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/ThreadPool.h b/extern/audaspace/include/util/ThreadPool.h
new file mode 100644
index 00000000000..24ec089d52c
--- /dev/null
+++ b/extern/audaspace/include/util/ThreadPool.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ThreadPool.h
+* @ingroup util
+* The ThreadPool class.
+*/
+
+#include "Audaspace.h"
+
+#include <mutex>
+#include <condition_variable>
+#include <vector>
+#include <thread>
+#include <queue>
+#include <future>
+#include <functional>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This represents pool of threads.
+*/
+class AUD_API ThreadPool
+{
+private:
+ /**
+ * A queue of tasks.
+ */
+ std::queue<std::function<void()>> m_queue;
+
+ /**
+ * A vector of thread objects.
+ */
+ std::vector<std::thread> m_threads;
+
+ /**
+ * A mutex for synchronization.
+ */
+ std::mutex m_mutex;
+
+ /**
+ * A condition variable used to stop the threads when there are no tasks.
+ */
+ std::condition_variable m_condition;
+
+ /**
+ * Stop flag.
+ */
+ bool m_stopFlag;
+
+ /**
+ * The number fo threads.
+ */
+ unsigned int m_numThreads;
+
+ // delete copy constructor and operator=
+ ThreadPool(const ThreadPool&) = delete;
+ ThreadPool& operator=(const ThreadPool&) = delete;
+public:
+ /**
+ * Creates a new ThreadPool object.
+ * \param count The number of threads of the pool. It must not be 0.
+ */
+ ThreadPool(unsigned int count);
+
+ virtual ~ThreadPool();
+
+ /**
+ * Enqueues a new task for the threads to realize.
+ * \param t A function that realices a task.
+ * \param args The arguments of the task.
+ * \return A future of the same type as the return type of the task.
+ */
+ template<class T, class... Args>
+ std::future<typename std::result_of<T(Args...)>::type> enqueue(T&& t, Args&&... args)
+ {
+ using pkgdTask = std::packaged_task<typename std::result_of<T(Args...)>::type()>;
+
+ std::shared_ptr<pkgdTask> task = std::make_shared<pkgdTask>(std::bind(std::forward<T>(t), std::forward<Args>(args)...));
+ auto result = task->get_future();
+
+ m_mutex.lock();
+ m_queue.emplace([task]() { (*task)(); });
+ m_mutex.unlock();
+
+ m_condition.notify_one();
+ return result;
+ }
+
+ /**
+ * Retrieves the number of threads of the pool.
+ * \return The number of threads.
+ */
+ unsigned int getNumOfThreads();
+
+private:
+
+ /**
+ * Worker thread function.
+ */
+ void threadFunction();
+};
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
new file mode 100644
index 00000000000..7f9b762f816
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "FFMPEG.h"
+#include "FFMPEGReader.h"
+#include "FFMPEGWriter.h"
+#include "file/FileManager.h"
+
+AUD_NAMESPACE_BEGIN
+
+FFMPEG::FFMPEG()
+{
+ av_register_all();
+}
+
+void FFMPEG::registerPlugin()
+{
+ std::shared_ptr<FFMPEG> plugin = std::shared_ptr<FFMPEG>(new FFMPEG);
+ FileManager::registerInput(plugin);
+ FileManager::registerOutput(plugin);
+}
+
+std::shared_ptr<IReader> FFMPEG::createReader(std::string filename)
+{
+ return std::shared_ptr<IReader>(new FFMPEGReader(filename));
+}
+
+std::shared_ptr<IReader> FFMPEG::createReader(std::shared_ptr<Buffer> buffer)
+{
+ return std::shared_ptr<IReader>(new FFMPEGReader(buffer));
+}
+
+std::shared_ptr<IWriter> FFMPEG::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return std::shared_ptr<IWriter>(new FFMPEGWriter(filename, specs, format, codec, bitrate));
+}
+
+#ifdef FFMPEG_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ FFMPEG::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "FFMPEG";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.h b/extern/audaspace/plugins/ffmpeg/FFMPEG.h
new file mode 100644
index 00000000000..108ba547e0f
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEG.h
+ * @ingroup plugin
+ * The FFMPEG class.
+ */
+
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This plugin class reads and writes sounds via ffmpeg.
+ */
+class AUD_PLUGIN_API FFMPEG : public IFileInput, public IFileOutput
+{
+private:
+ // delete copy constructor and operator=
+ FFMPEG(const FFMPEG&) = delete;
+ FFMPEG& operator=(const FFMPEG&) = delete;
+
+public:
+ /**
+ * Creates a new ffmpeg plugin.
+ */
+ FFMPEG();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+
+ virtual std::shared_ptr<IReader> createReader(std::string filename);
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
new file mode 100644
index 00000000000..6b79cc5abfd
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "FFMPEGReader.h"
+#include "Exception.h"
+
+#include <algorithm>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avio.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
+{
+ AVFrame* frame = nullptr;
+ int got_frame;
+ int read_length;
+ uint8_t* orig_data = packet.data;
+ int orig_size = packet.size;
+
+ int buf_size = buffer.getSize();
+ int buf_pos = 0;
+
+ while(packet.size > 0)
+ {
+ got_frame = 0;
+
+ if(!frame)
+ frame = av_frame_alloc();
+ else
+ av_frame_unref(frame);
+
+ read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
+ if(read_length < 0)
+ break;
+
+ if(got_frame)
+ {
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
+
+ if(buf_size - buf_pos < data_size)
+ {
+ buffer.resize(buf_size + data_size, true);
+ buf_size += data_size;
+ }
+
+ if(m_tointerleave)
+ {
+ int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
+ for(int channel = 0; channel < m_codecCtx->channels; channel++)
+ {
+ for(int i = 0; i < frame->nb_samples; i++)
+ {
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+ frame->data[channel] + i * single_size, single_size);
+ }
+ }
+ }
+ else
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
+
+ buf_pos += data_size;
+ }
+ packet.size -= read_length;
+ packet.data += read_length;
+ }
+
+ packet.data = orig_data;
+ packet.size = orig_size;
+ av_free(frame);
+
+ return buf_pos;
+}
+
+void FFMPEGReader::init()
+{
+ m_position = 0;
+ m_pkgbuf_left = 0;
+
+ if(avformat_find_stream_info(m_formatCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg couldn't find the stream info.");
+
+ // find audio stream and codec
+ m_stream = -1;
+
+ for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
+ {
+ if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ }
+
+ if(m_stream == -1)
+ AUD_THROW(FileException, "File couldn't be read, no audio stream found by ffmpeg.");
+
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+ // get a decoder and open it
+ AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+ if(!aCodec)
+ AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");
+
+ if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
+
+ m_specs.channels = (Channels) m_codecCtx->channels;
+ m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+
+ switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
+ {
+ case AV_SAMPLE_FMT_U8:
+ m_convert = convert_u8_float;
+ m_specs.format = FORMAT_U8;
+ break;
+ case AV_SAMPLE_FMT_S16:
+ m_convert = convert_s16_float;
+ m_specs.format = FORMAT_S16;
+ break;
+ case AV_SAMPLE_FMT_S32:
+ m_convert = convert_s32_float;
+ m_specs.format = FORMAT_S32;
+ break;
+ case AV_SAMPLE_FMT_FLT:
+ m_convert = convert_copy<float>;
+ m_specs.format = FORMAT_FLOAT32;
+ break;
+ case AV_SAMPLE_FMT_DBL:
+ m_convert = convert_double_float;
+ m_specs.format = FORMAT_FLOAT64;
+ break;
+ default:
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg sample format unknown.");
+ }
+
+ m_specs.rate = (SampleRate) m_codecCtx->sample_rate;
+}
+
+FFMPEGReader::FFMPEGReader(std::string filename) :
+ m_pkgbuf(),
+ m_formatCtx(nullptr),
+ m_aviocontext(nullptr),
+ m_membuf(nullptr)
+{
+ // open file
+ if(avformat_open_input(&m_formatCtx, filename.c_str(), nullptr, nullptr)!=0)
+ AUD_THROW(FileException, "File couldn't be opened with ffmpeg.");
+
+ try
+ {
+ init();
+ }
+ catch(Exception&)
+ {
+ avformat_close_input(&m_formatCtx);
+ throw;
+ }
+}
+
+FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
+ m_pkgbuf(),
+ m_membuffer(buffer),
+ m_membufferpos(0)
+{
+ m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
+
+ m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this, read_packet, nullptr, seek_packet);
+
+ if(!m_aviocontext)
+ {
+ av_free(m_aviocontext);
+ AUD_THROW(FileException, "Buffer reading context couldn't be created with ffmpeg.");
+ }
+
+ m_formatCtx = avformat_alloc_context();
+ m_formatCtx->pb = m_aviocontext;
+ if(avformat_open_input(&m_formatCtx, "", nullptr, nullptr)!=0)
+ {
+ av_free(m_aviocontext);
+ AUD_THROW(FileException, "Buffer couldn't be read with ffmpeg.");
+ }
+
+ try
+ {
+ init();
+ }
+ catch(Exception&)
+ {
+ avformat_close_input(&m_formatCtx);
+ av_free(m_aviocontext);
+ throw;
+ }
+}
+
+FFMPEGReader::~FFMPEGReader()
+{
+ avcodec_close(m_codecCtx);
+ avformat_close_input(&m_formatCtx);
+}
+
+int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
+{
+ FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
+
+ int size = std::min(buf_size, int(reader->m_membuffer->getSize() - reader->m_membufferpos));
+
+ if(size < 0)
+ return -1;
+
+ std::memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
+ reader->m_membufferpos += size;
+
+ return size;
+}
+
+int64_t FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
+{
+ FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_membufferpos = 0;
+ break;
+ case SEEK_END:
+ reader->m_membufferpos = reader->m_membuffer->getSize();
+ break;
+ case AVSEEK_SIZE:
+ return reader->m_membuffer->getSize();
+ }
+
+ return (reader->m_membufferpos += offset);
+}
+
+bool FFMPEGReader::isSeekable() const
+{
+ return true;
+}
+
+void FFMPEGReader::seek(int position)
+{
+ if(position >= 0)
+ {
+ uint64_t st_time = m_formatCtx->start_time;
+ uint64_t seek_pos = ((uint64_t)position) * ((uint64_t)AV_TIME_BASE) / ((uint64_t)m_specs.rate);
+
+ if(st_time != AV_NOPTS_VALUE) {
+ seek_pos += st_time;
+ }
+
+ double pts_time_base =
+ av_q2d(m_formatCtx->streams[m_stream]->time_base);
+ uint64_t pts_st_time =
+ ((st_time != AV_NOPTS_VALUE) ? st_time : 0)
+ / pts_time_base / (uint64_t) AV_TIME_BASE;
+
+ // a value < 0 tells us that seeking failed
+ if(av_seek_frame(m_formatCtx, -1, seek_pos,
+ AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
+ {
+ avcodec_flush_buffers(m_codecCtx);
+ m_position = position;
+
+ AVPacket packet;
+ bool search = true;
+
+ while(search && av_read_frame(m_formatCtx, &packet) >= 0)
+ {
+ // is it a frame from the audio stream?
+ if(packet.stream_index == m_stream)
+ {
+ // decode the package
+ m_pkgbuf_left = decode(packet, m_pkgbuf);
+ search = false;
+
+ // check position
+ if(packet.pts != AV_NOPTS_VALUE)
+ {
+ // calculate real position, and read to frame!
+ m_position = (packet.pts - pts_st_time) * pts_time_base * m_specs.rate;
+
+ if(m_position < position)
+ {
+ // read until we're at the right position
+ int length = AUD_DEFAULT_BUFFER_SIZE;
+ Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs));
+ bool eos;
+ for(int len = position - m_position; len > 0; len -= AUD_DEFAULT_BUFFER_SIZE)
+ {
+ if(len < AUD_DEFAULT_BUFFER_SIZE)
+ length = len;
+ read(length, eos, buffer.getBuffer());
+ }
+ }
+ }
+ }
+ av_free_packet(&packet);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "seeking failed!\n");
+ // Seeking failed, do nothing.
+ }
+ }
+}
+
+int FFMPEGReader::getLength() const
+{
+ // return approximated remaning size
+ return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
+ / AV_TIME_BASE)-m_position;
+}
+
+int FFMPEGReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs FFMPEGReader::getSpecs() const
+{
+ return m_specs.specs;
+}
+
+void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // read packages and decode them
+ AVPacket packet;
+ int data_size = 0;
+ int pkgbuf_pos;
+ int left = length;
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
+
+ sample_t* buf = buffer;
+ pkgbuf_pos = m_pkgbuf_left;
+ m_pkgbuf_left = 0;
+
+ // there may still be data in the buffer from the last call
+ if(pkgbuf_pos > 0)
+ {
+ data_size = std::min(pkgbuf_pos, left * sample_size);
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ left -= data_size/sample_size;
+ }
+
+ // for each frame read as long as there isn't enough data already
+ while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
+ {
+ // is it a frame from the audio stream?
+ if(packet.stream_index == m_stream)
+ {
+ // decode the package
+ pkgbuf_pos = decode(packet, m_pkgbuf);
+
+ // copy to output buffer
+ data_size = std::min(pkgbuf_pos, left * sample_size);
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ left -= data_size/sample_size;
+ }
+ av_free_packet(&packet);
+ }
+ // read more data than necessary?
+ if(pkgbuf_pos > data_size)
+ {
+ m_pkgbuf_left = pkgbuf_pos-data_size;
+ memmove(m_pkgbuf.getBuffer(),
+ ((data_t*)m_pkgbuf.getBuffer())+data_size,
+ pkgbuf_pos-data_size);
+ }
+
+ if((eos = (left > 0)))
+ length -= left;
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
new file mode 100644
index 00000000000..e2ae959912d
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEGReader.h
+ * @ingroup plugin
+ * The FFMPEGReader class.
+ */
+
+#include "respec/ConverterFunctions.h"
+#include "IReader.h"
+#include "util/Buffer.h"
+
+#include <string>
+#include <memory>
+
+struct AVCodecContext;
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads a sound file via ffmpeg.
+ * \warning Seeking may not be accurate! Moreover the position is updated after
+ * a buffer reading call. So calling getPosition right after seek
+ * normally results in a wrong value.
+ */
+class AUD_PLUGIN_API FFMPEGReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The buffer for package reading.
+ */
+ Buffer m_pkgbuf;
+
+ /**
+ * The count of samples still available from the last read package.
+ */
+ int m_pkgbuf_left;
+
+ /**
+ * The AVFormatContext structure for using ffmpeg.
+ */
+ AVFormatContext* m_formatCtx;
+
+ /**
+ * The AVCodecContext structure for using ffmpeg.
+ */
+ AVCodecContext* m_codecCtx;
+
+ /**
+ * The AVIOContext to read the data from.
+ */
+ AVIOContext* m_aviocontext;
+
+ /**
+ * The stream ID in the file.
+ */
+ int m_stream;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ /**
+ * The memory file to read from.
+ */
+ std::shared_ptr<Buffer> m_membuffer;
+
+ /**
+ * The buffer to read with.
+ */
+ data_t* m_membuf;
+
+ /**
+ * Reading position of the buffer.
+ */
+ int64_t m_membufferpos;
+
+ /**
+ * Whether the audio data has to be interleaved after reading.
+ */
+ bool m_tointerleave;
+
+ /**
+ * Decodes a packet into the given buffer.
+ * \param packet The AVPacket to decode.
+ * \param buffer The target buffer.
+ * \return The count of read bytes.
+ */
+ AUD_LOCAL int decode(AVPacket& packet, Buffer& buffer);
+
+ /**
+ * Initializes the object.
+ */
+ AUD_LOCAL void init();
+
+ // delete copy constructor and operator=
+ FFMPEGReader(const FFMPEGReader&) = delete;
+ FFMPEGReader& operator=(const FFMPEGReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param filename The path to the file to be read.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with ffmpeg.
+ */
+ FFMPEGReader(std::string filename);
+
+ /**
+ * Creates a new reader.
+ * \param buffer The buffer to read from.
+ * \exception Exception Thrown if the buffer specified cannot be read
+ * with ffmpeg.
+ */
+ FFMPEGReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~FFMPEGReader();
+
+ /**
+ * Reads data to a memory buffer.
+ * This function is used for avio only.
+ * @param opaque The FFMPEGReader.
+ * @param buf The buffer to read to.
+ * @param buf_size The size of the buffer.
+ * @return How many bytes have been read.
+ */
+ static int read_packet(void* opaque, uint8_t* buf, int buf_size);
+
+ /**
+ * Seeks within data.
+ * This function is used for avio only.
+ * @param opaque The FFMPEGReader.
+ * @param offset The byte offset to seek to.
+ * @param whence The seeking action.
+ * @return The current position or the size of the data if requested.
+ */
+ static int64_t seek_packet(void* opaque, int64_t offset, int whence);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
new file mode 100644
index 00000000000..f79f0f7fc6b
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "FFMPEGWriter.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <cstring>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avio.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+void FFMPEGWriter::encode()
+{
+ sample_t* data = m_input_buffer.getBuffer();
+
+ if(m_deinterleave)
+ {
+ m_deinterleave_buffer.assureSize(m_input_buffer.getSize());
+
+ sample_t* dbuf = m_deinterleave_buffer.getBuffer();
+ // deinterleave
+ int single_size = sizeof(sample_t);
+ for(int channel = 0; channel < m_specs.channels; channel++)
+ {
+ for(int i = 0; i < m_input_buffer.getSize() / AUD_SAMPLE_SIZE(m_specs); i++)
+ {
+ std::memcpy(((data_t*)dbuf) + (m_input_samples * channel + i) * single_size,
+ ((data_t*)data) + ((m_specs.channels * i) + channel) * single_size, single_size);
+ }
+ }
+
+ // convert first
+ if(m_input_size)
+ m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(dbuf), m_input_samples * m_specs.channels);
+ else
+ std::memcpy(data, dbuf, m_input_buffer.getSize());
+ }
+ else
+ // convert first
+ if(m_input_size)
+ m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_samples * m_specs.channels);
+
+ AVPacket packet;
+
+ packet.data = nullptr;
+ packet.size = 0;
+
+ av_init_packet(&packet);
+
+ AVFrame* frame = av_frame_alloc();
+ av_frame_unref(frame);
+ int got_packet;
+
+ frame->nb_samples = m_input_samples;
+ frame->format = m_codecCtx->sample_fmt;
+ frame->channel_layout = m_codecCtx->channel_layout;
+
+ if(avcodec_fill_audio_frame(frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
+ AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
+
+ AVRational sample_time = { 1, static_cast<int>(m_specs.rate) };
+ frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
+
+ if(avcodec_encode_audio2(m_codecCtx, &packet, frame, &got_packet))
+ {
+ av_frame_free(&frame);
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+ }
+
+ if(got_packet)
+ {
+ packet.flags |= AV_PKT_FLAG_KEY;
+ packet.stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, &packet) < 0)
+ {
+ av_free_packet(&packet);
+ av_frame_free(&frame);
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+ av_free_packet(&packet);
+ }
+
+ av_frame_free(&frame);
+}
+
+void FFMPEGWriter::close()
+{
+ int got_packet = true;
+
+ while(got_packet)
+ {
+ AVPacket packet;
+
+ packet.data = nullptr;
+ packet.size = 0;
+
+ av_init_packet(&packet);
+
+ if(avcodec_encode_audio2(m_codecCtx, &packet, nullptr, &got_packet))
+ AUD_THROW(FileException, "File end couldn't be written, audio encoding failed with ffmpeg.");
+
+ if(got_packet)
+ {
+ packet.flags |= AV_PKT_FLAG_KEY;
+ packet.stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, &packet))
+ {
+ av_free_packet(&packet);
+ AUD_THROW(FileException, "Final frames couldn't be writen to the file with ffmpeg.");
+ }
+ av_free_packet(&packet);
+ }
+ }
+}
+
+FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
+ m_position(0),
+ m_specs(specs),
+ m_input_samples(0),
+ m_deinterleave(false)
+{
+ static const char* formats[] = { nullptr, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
+
+ if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
+ AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
+
+ m_outputFmt = m_formatCtx->oformat;
+
+ if(!m_outputFmt) {
+ avformat_free_context(m_formatCtx);
+ AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
+ }
+
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+
+ switch(codec)
+ {
+ case CODEC_AAC:
+ m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
+ break;
+ case CODEC_AC3:
+ m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
+ break;
+ case CODEC_FLAC:
+ m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
+ break;
+ case CODEC_MP2:
+ m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
+ break;
+ case CODEC_MP3:
+ m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
+ break;
+ case CODEC_OPUS:
+ m_outputFmt->audio_codec = AV_CODEC_ID_OPUS;
+ break;
+ case CODEC_PCM:
+ switch(specs.format)
+ {
+ case FORMAT_U8:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
+ break;
+ case FORMAT_S16:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ break;
+ case FORMAT_S24:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
+ break;
+ case FORMAT_S32:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
+ break;
+ case FORMAT_FLOAT32:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
+ break;
+ case FORMAT_FLOAT64:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
+ break;
+ default:
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+ break;
+ case CODEC_VORBIS:
+ m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
+ break;
+ default:
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+
+ try
+ {
+ if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
+ AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
+
+ AVCodec* codec = avcodec_find_encoder(m_outputFmt->audio_codec);
+ if(!codec)
+ AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");
+
+ m_stream = avformat_new_stream(m_formatCtx, codec);
+ if(!m_stream)
+ AUD_THROW(FileException, "File couldn't be written, stream creation failed with ffmpeg.");
+
+ m_stream->id = m_formatCtx->nb_streams - 1;
+
+ m_codecCtx = m_stream->codec;
+
+ switch(m_specs.format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_U8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S32;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_DBL;
+ break;
+ default:
+ m_convert = convert_copy<sample_t>;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ break;
+ }
+
+ if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
+ m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ bool format_supported = false;
+
+ for(int i = 0; codec->sample_fmts[i] != -1; i++)
+ {
+ if(av_get_alt_sample_fmt(codec->sample_fmts[i], false) == m_codecCtx->sample_fmt)
+ {
+ m_deinterleave = av_sample_fmt_is_planar(codec->sample_fmts[i]);
+ m_codecCtx->sample_fmt = codec->sample_fmts[i];
+ format_supported = true;
+ }
+ }
+
+ if(!format_supported)
+ {
+ int chosen_index = 0;
+ auto chosen = av_get_alt_sample_fmt(codec->sample_fmts[chosen_index], false);
+ for(int i = 1; codec->sample_fmts[i] != -1; i++)
+ {
+ auto fmt = av_get_alt_sample_fmt(codec->sample_fmts[i], false);
+ if((fmt > chosen && chosen < m_codecCtx->sample_fmt) || (fmt > m_codecCtx->sample_fmt && fmt < chosen))
+ {
+ chosen = fmt;
+ chosen_index = i;
+ }
+ }
+
+ m_codecCtx->sample_fmt = codec->sample_fmts[chosen_index];
+ m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+ switch(av_get_alt_sample_fmt(m_codecCtx->sample_fmt, false))
+ {
+ case AV_SAMPLE_FMT_U8:
+ specs.format = FORMAT_U8;
+ m_convert = convert_float_u8;
+ break;
+ case AV_SAMPLE_FMT_S16:
+ specs.format = FORMAT_S16;
+ m_convert = convert_float_s16;
+ break;
+ case AV_SAMPLE_FMT_S32:
+ specs.format = FORMAT_S32;
+ m_convert = convert_float_s32;
+ break;
+ case AV_SAMPLE_FMT_FLT:
+ specs.format = FORMAT_FLOAT32;
+ m_convert = convert_copy<sample_t>;
+ break;
+ case AV_SAMPLE_FMT_DBL:
+ specs.format = FORMAT_FLOAT64;
+ m_convert = convert_float_double;
+ break;
+ default:
+ AUD_THROW(FileException, "File couldn't be written, sample format not supported with ffmpeg.");
+ }
+ }
+
+ m_codecCtx->sample_rate = 0;
+
+ if(codec->supported_samplerates)
+ {
+ for(int i = 0; codec->supported_samplerates[i]; i++)
+ {
+ if(codec->supported_samplerates[i] == m_specs.rate)
+ {
+ m_codecCtx->sample_rate = codec->supported_samplerates[i];
+ break;
+ }
+ else if((codec->supported_samplerates[i] > m_codecCtx->sample_rate && m_specs.rate > m_codecCtx->sample_rate) ||
+ (codec->supported_samplerates[i] < m_codecCtx->sample_rate && m_specs.rate < codec->supported_samplerates[i]))
+ {
+ m_codecCtx->sample_rate = codec->supported_samplerates[i];
+ }
+ }
+ }
+
+ if(m_codecCtx->sample_rate == 0)
+ m_codecCtx->sample_rate = m_specs.rate;
+
+ m_specs.rate = m_codecCtx->sample_rate;
+
+ m_codecCtx->codec_id = m_outputFmt->audio_codec;
+ m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
+ m_codecCtx->bit_rate = bitrate;
+ m_codecCtx->channels = m_specs.channels;
+ m_stream->time_base.num = m_codecCtx->time_base.num = 1;
+ m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;
+
+ if(avcodec_open2(m_codecCtx, codec, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, encoder couldn't be opened with ffmpeg.");
+
+ int samplesize = std::max(int(AUD_SAMPLE_SIZE(m_specs)), AUD_DEVICE_SAMPLE_SIZE(m_specs));
+
+ if((m_input_size = m_codecCtx->frame_size))
+ m_input_buffer.resize(m_input_size * samplesize);
+
+ if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
+ AUD_THROW(FileException, "File couldn't be written, file opening failed with ffmpeg.");
+
+ avformat_write_header(m_formatCtx, nullptr);
+ }
+ catch(Exception&)
+ {
+ avformat_free_context(m_formatCtx);
+ throw;
+ }
+}
+
+FFMPEGWriter::~FFMPEGWriter()
+{
+ // writte missing data
+ if(m_input_samples)
+ encode();
+
+ close();
+
+ av_write_trailer(m_formatCtx);
+
+ avcodec_close(m_codecCtx);
+
+ avio_close(m_formatCtx->pb);
+ avformat_free_context(m_formatCtx);
+}
+
+int FFMPEGWriter::getPosition() const
+{
+ return m_position;
+}
+
+DeviceSpecs FFMPEGWriter::getSpecs() const
+{
+ return m_specs;
+}
+
+void FFMPEGWriter::write(unsigned int length, sample_t* buffer)
+{
+ unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
+
+ if(m_input_size)
+ {
+ sample_t* inbuf = m_input_buffer.getBuffer();
+
+ while(length)
+ {
+ unsigned int len = std::min(m_input_size - m_input_samples, length);
+
+ std::memcpy(inbuf + m_input_samples * m_specs.channels, buffer, len * samplesize);
+
+ buffer += len * m_specs.channels;
+ m_input_samples += len;
+ m_position += len;
+ length -= len;
+
+ if(m_input_samples == m_input_size)
+ {
+ encode();
+
+ m_input_samples = 0;
+ }
+ }
+ }
+ else // PCM data, can write directly!
+ {
+ int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ m_input_buffer.assureSize(length * std::max(AUD_DEVICE_SAMPLE_SIZE(m_specs), samplesize));
+
+ sample_t* buf = m_input_buffer.getBuffer();
+ m_convert(reinterpret_cast<data_t*>(buf), reinterpret_cast<data_t*>(buffer), length * m_specs.channels);
+
+ m_input_samples = length;
+
+ m_position += length;
+
+ encode();
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
new file mode 100644
index 00000000000..690185deb64
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEGWriter.h
+ * @ingroup plugin
+ * The FFMPEGWriter class.
+ */
+
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+#include "file/IWriter.h"
+
+#include <string>
+
+struct AVCodecContext;
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class writes a sound file via ffmpeg.
+ */
+class AUD_PLUGIN_API FFMPEGWriter : public IWriter
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The AVFormatContext structure for using ffmpeg.
+ */
+ AVFormatContext* m_formatCtx;
+
+ /**
+ * The AVCodecContext structure for using ffmpeg.
+ */
+ AVCodecContext* m_codecCtx;
+
+ /**
+ * The AVOutputFormat structure for using ffmpeg.
+ */
+ AVOutputFormat* m_outputFmt;
+
+ /**
+ * The AVStream structure for using ffmpeg.
+ */
+ AVStream* m_stream;
+
+ /**
+ * The input buffer for the format converted data before encoding.
+ */
+ Buffer m_input_buffer;
+
+ /**
+ * The buffer used for deinterleaving.
+ */
+ Buffer m_deinterleave_buffer;
+
+ /**
+ * The count of input samples we have so far.
+ */
+ unsigned int m_input_samples;
+
+ /**
+ * The count of input samples necessary to encode a packet.
+ */
+ unsigned int m_input_size;
+
+ /**
+ * Whether the ouput has to be deinterleaved before writing.
+ */
+ bool m_deinterleave;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ // delete copy constructor and operator=
+ FFMPEGWriter(const FFMPEGWriter&) = delete;
+ FFMPEGWriter& operator=(const FFMPEGWriter&) = delete;
+
+ /**
+ * Encodes to the output buffer.
+ */
+ AUD_LOCAL void encode();
+
+ /**
+ * Finishes writing to the file.
+ */
+ AUD_LOCAL void close();
+
+public:
+ /**
+ * Creates a new writer.
+ * \param filename The path to the file to be read.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with ffmpeg.
+ */
+ FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Destroys the writer and closes the file.
+ */
+ virtual ~FFMPEGWriter();
+
+ virtual int getPosition() const;
+ virtual DeviceSpecs getSpecs() const;
+ virtual void write(unsigned int length, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackDevice.cpp b/extern/audaspace/plugins/jack/JackDevice.cpp
new file mode 100644
index 00000000000..1d238f74c3a
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackDevice.cpp
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "JackDevice.h"
+#include "JackLibrary.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "Exception.h"
+#include "IReader.h"
+
+#include <cstring>
+#include <algorithm>
+
+AUD_NAMESPACE_BEGIN
+
+void JackDevice::updateRingBuffers()
+{
+ size_t size, temp;
+ unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ unsigned int i, j;
+ unsigned int channels = m_specs.channels;
+ sample_t* buffer = m_buffer.getBuffer();
+ float* deinterleave = m_deinterleavebuf.getBuffer();
+ jack_transport_state_t state;
+ jack_position_t position;
+
+ std::unique_lock<std::mutex> lock(m_mixingLock);
+
+ while(m_valid)
+ {
+ if(m_sync > 1)
+ {
+ if(m_syncFunc)
+ {
+ state = AUD_jack_transport_query(m_client, &position);
+ m_syncFunc(m_syncFuncData, state != JackTransportStopped, position.frame / (float) m_specs.rate);
+ }
+
+ for(i = 0; i < channels; i++)
+ AUD_jack_ringbuffer_reset(m_ringbuffers[i]);
+ }
+
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
+ for(i = 1; i < channels; i++)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ size = temp;
+
+ while(size > samplesize)
+ {
+ size /= samplesize;
+ mix((data_t*)buffer, size);
+ for(i = 0; i < channels; i++)
+ {
+ for(j = 0; j < size; j++)
+ deinterleave[i * size + j] = buffer[i + j * channels];
+ AUD_jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
+ }
+
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
+ for(i = 1; i < channels; i++)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ size = temp;
+ }
+
+ if(m_sync > 1)
+ {
+ m_sync = 3;
+ }
+
+ m_mixingCondition.wait(lock);
+ }
+}
+
+int JackDevice::jack_mix(jack_nframes_t length, void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+ unsigned int i;
+ int count = device->m_specs.channels;
+ char* buffer;
+
+ if(device->m_sync)
+ {
+ // play silence while syncing
+ for(unsigned int i = 0; i < count; i++)
+ std::memset(AUD_jack_port_get_buffer(device->m_ports[i], length), 0, length * sizeof(float));
+ }
+ else
+ {
+ size_t temp;
+ size_t readsamples = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[0]);
+ for(i = 1; i < count; i++)
+ if((temp = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
+ readsamples = temp;
+
+ readsamples = std::min(readsamples / sizeof(float), size_t(length));
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ buffer = (char*)AUD_jack_port_get_buffer(device->m_ports[i], length);
+ AUD_jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
+ if(readsamples < length)
+ std::memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
+ }
+
+ if(device->m_mixingLock.try_lock())
+ {
+ device->m_mixingCondition.notify_all();
+ device->m_mixingLock.unlock();
+ }
+ }
+
+ return 0;
+}
+
+int JackDevice::jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+
+ if(state == JackTransportStopped)
+ return 1;
+
+ if(device->m_mixingLock.try_lock())
+ {
+ if(device->m_sync > 2)
+ {
+ if(device->m_sync == 3)
+ {
+ device->m_sync = 0;
+ device->m_mixingLock.unlock();
+ return 1;
+ }
+ }
+ else
+ {
+ device->m_sync = 2;
+ device->m_mixingCondition.notify_all();
+ }
+ device->m_mixingLock.unlock();
+ }
+ else if(!device->m_sync)
+ device->m_sync = 1;
+
+ return 0;
+}
+
+void JackDevice::jack_shutdown(void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+ device->m_valid = false;
+}
+
+JackDevice::JackDevice(std::string name, DeviceSpecs specs, int buffersize) :
+ m_synchronizer(this)
+{
+ if(specs.channels == CHANNELS_INVALID)
+ specs.channels = CHANNELS_STEREO;
+
+ // jack uses floats
+ m_specs = specs;
+ m_specs.format = FORMAT_FLOAT32;
+
+ jack_options_t options = JackNullOption;
+ jack_status_t status;
+
+ // open client
+ m_client = AUD_jack_client_open(name.c_str(), options, &status);
+ if(m_client == nullptr)
+ AUD_THROW(DeviceException, "Connecting to the JACK server failed.");
+
+ // set callbacks
+ AUD_jack_set_process_callback(m_client, JackDevice::jack_mix, this);
+ AUD_jack_on_shutdown(m_client, JackDevice::jack_shutdown, this);
+ AUD_jack_set_sync_callback(m_client, JackDevice::jack_sync, this);
+
+ // register our output channels which are called ports in jack
+ m_ports = new jack_port_t*[m_specs.channels];
+
+ try
+ {
+ char portname[64];
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ sprintf(portname, "out %d", i+1);
+ m_ports[i] = AUD_jack_port_register(m_client, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ if(m_ports[i] == nullptr)
+ AUD_THROW(DeviceException, "Registering output port with JACK failed.");
+ }
+ }
+ catch(Exception&)
+ {
+ AUD_jack_client_close(m_client);
+ delete[] m_ports;
+ throw;
+ }
+
+ m_specs.rate = (SampleRate)AUD_jack_get_sample_rate(m_client);
+
+ buffersize *= sizeof(sample_t);
+ m_ringbuffers = new jack_ringbuffer_t*[specs.channels];
+ for(unsigned int i = 0; i < specs.channels; i++)
+ m_ringbuffers[i] = AUD_jack_ringbuffer_create(buffersize);
+ buffersize *= specs.channels;
+ m_deinterleavebuf.resize(buffersize);
+ m_buffer.resize(buffersize);
+
+ create();
+
+ m_valid = true;
+ m_sync = 0;
+ m_syncFunc = nullptr;
+ m_nextState = m_state = AUD_jack_transport_query(m_client, nullptr);
+
+ // activate the client
+ if(AUD_jack_activate(m_client))
+ {
+ AUD_jack_client_close(m_client);
+ delete[] m_ports;
+ for(unsigned int i = 0; i < specs.channels; i++)
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
+ delete[] m_ringbuffers;
+ destroy();
+
+ AUD_THROW(DeviceException, "Client activation with JACK failed.");
+ }
+
+ const char** ports = AUD_jack_get_ports(m_client, nullptr, nullptr,
+ JackPortIsPhysical | JackPortIsInput);
+ if(ports != nullptr)
+ {
+ for(int i = 0; i < m_specs.channels && ports[i]; i++)
+ AUD_jack_connect(m_client, AUD_jack_port_name(m_ports[i]), ports[i]);
+
+ AUD_jack_free(ports);
+ }
+
+ m_mixingThread = std::thread(&JackDevice::updateRingBuffers, this);
+}
+
+JackDevice::~JackDevice()
+{
+ if(m_valid)
+ AUD_jack_client_close(m_client);
+ m_valid = false;
+
+ delete[] m_ports;
+
+ m_mixingLock.lock();
+ m_mixingCondition.notify_all();
+ m_mixingLock.unlock();
+
+ m_mixingThread.join();
+
+ for(unsigned int i = 0; i < m_specs.channels; i++)
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
+ delete[] m_ringbuffers;
+
+ destroy();
+}
+
+ISynchronizer* JackDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+void JackDevice::playing(bool playing)
+{
+ // Do nothing.
+}
+
+void JackDevice::startPlayback()
+{
+ AUD_jack_transport_start(m_client);
+ m_nextState = JackTransportRolling;
+}
+
+void JackDevice::stopPlayback()
+{
+ AUD_jack_transport_stop(m_client);
+ m_nextState = JackTransportStopped;
+}
+
+void JackDevice::seekPlayback(float time)
+{
+ if(time >= 0.0f)
+ AUD_jack_transport_locate(m_client, time * m_specs.rate);
+}
+
+void JackDevice::setSyncCallback(ISynchronizer::syncFunction sync, void* data)
+{
+ m_syncFunc = sync;
+ m_syncFuncData = data;
+}
+
+float JackDevice::getPlaybackPosition()
+{
+ jack_position_t position;
+ AUD_jack_transport_query(m_client, &position);
+ return position.frame / (float) m_specs.rate;
+}
+
+bool JackDevice::doesPlayback()
+{
+ jack_transport_state_t state = AUD_jack_transport_query(m_client, nullptr);
+
+ if(state != m_state)
+ m_nextState = m_state = state;
+
+ return m_nextState != JackTransportStopped;
+}
+
+class JackDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+ std::string m_name;
+
+public:
+ JackDeviceFactory() :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE),
+ m_name("Audaspace")
+ {
+ m_specs.format = FORMAT_FLOAT32;
+ m_specs.channels = CHANNELS_STEREO;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new JackDevice(m_name, m_specs, m_buffersize));
+ }
+
+ virtual int getPriority()
+ {
+ return 0;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ m_name = name;
+ }
+};
+
+void JackDevice::registerPlugin()
+{
+ if(loadJACK())
+ DeviceManager::registerDevice("JACK", std::shared_ptr<IDeviceFactory>(new JackDeviceFactory));
+}
+
+#ifdef JACK_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ JackDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "JACK";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/extern/audaspace/plugins/jack/JackDevice.h
index ccf3bfd6341..72143eda149 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/extern/audaspace/plugins/jack/JackDevice.h
@@ -1,49 +1,47 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/jack/AUD_JackDevice.h
- * \ingroup audjack
- */
+#pragma once
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
-#ifndef __AUD_JACKDEVICE_H__
-#define __AUD_JACKDEVICE_H__
-
+/**
+ * @file JackDevice.h
+ * @ingroup plugin
+ * The JackDevice class.
+ */
-#include "AUD_SoftwareDevice.h"
-#include "AUD_Buffer.h"
+#include "JackSynchronizer.h"
+#include "devices/SoftwareDevice.h"
+#include "util/Buffer.h"
#include <string>
+#include <condition_variable>
+#include <thread>
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
-#include <AUD_JackLibrary.h>
-
-typedef void (*AUD_syncFunction)(void*, int, float);
+AUD_NAMESPACE_BEGIN
/**
* This device plays back through JACK.
*/
-class AUD_JackDevice : public AUD_SoftwareDevice
+class AUD_PLUGIN_API JackDevice : public SoftwareDevice
{
private:
/**
@@ -59,12 +57,12 @@ private:
/**
* The output buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* The deinterleaving buffer.
*/
- AUD_Buffer m_deinterleavebuf;
+ Buffer m_deinterleavebuf;
jack_ringbuffer_t** m_ringbuffers;
@@ -73,11 +71,14 @@ private:
*/
bool m_valid;
+ /// Synchronizer.
+ JackSynchronizer m_synchronizer;
+
/**
* Invalidates the jack device.
* \param data The jack device that gets invalidet by jack.
*/
- static void jack_shutdown(void *data);
+ AUD_LOCAL static void jack_shutdown(void* data);
/**
* Mixes the next bytes into the buffer.
@@ -85,9 +86,9 @@ private:
* \param data A pointer to the jack device.
* \return 0 what shows success.
*/
- static int jack_mix(jack_nframes_t length, void *data);
+ AUD_LOCAL static int jack_mix(jack_nframes_t length, void* data);
- static int jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data);
+ AUD_LOCAL static int jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data);
/**
* Next JACK Transport state (-1 if not expected to change).
@@ -107,7 +108,7 @@ private:
/**
* External syncronisation callback function.
*/
- AUD_syncFunction m_syncFunc;
+ ISynchronizer::syncFunction m_syncFunc;
/**
* Data for the sync function.
@@ -117,33 +118,26 @@ private:
/**
* The mixing thread.
*/
- pthread_t m_mixingThread;
+ std::thread m_mixingThread;
/**
* Mutex for mixing.
*/
- pthread_mutex_t m_mixingLock;
+ std::mutex m_mixingLock;
/**
* Condition for mixing.
*/
- pthread_cond_t m_mixingCondition;
-
- /**
- * Mixing thread function.
- * \param device The this pointer.
- * \return NULL.
- */
- static void* runMixingThread(void* device);
+ std::condition_variable m_mixingCondition;
/**
* Updates the ring buffers.
*/
- void updateRingBuffers();
+ AUD_LOCAL void updateRingBuffers();
- // hide copy constructor and operator=
- AUD_JackDevice(const AUD_JackDevice&);
- AUD_JackDevice& operator=(const AUD_JackDevice&);
+ // delete copy constructor and operator=
+ JackDevice(const JackDevice&) = delete;
+ JackDevice& operator=(const JackDevice&) = delete;
protected:
virtual void playing(bool playing);
@@ -155,14 +149,16 @@ public:
* \param specs The wanted audio specification, where only the channel count
* is important.
* \param buffersize The size of the internal buffer.
- * \exception AUD_Exception Thrown if the audio device cannot be opened.
+ * \exception Exception Thrown if the audio device cannot be opened.
*/
- AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ JackDevice(std::string name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the JACK client.
*/
- virtual ~AUD_JackDevice();
+ virtual ~JackDevice();
+
+ virtual ISynchronizer* getSynchronizer();
/**
* Starts jack transport playback.
@@ -185,7 +181,7 @@ public:
* \param sync The callback function.
* \param data The data for the function.
*/
- void setSyncCallback(AUD_syncFunction sync, void* data);
+ void setSyncCallback(ISynchronizer::syncFunction sync, void* data);
/**
* Retrieves the jack transport playback time.
@@ -198,6 +194,11 @@ public:
* \return Whether jack transport plays back.
*/
bool doesPlayback();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
};
-#endif //__AUD_JACKDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackLibrary.cpp b/extern/audaspace/plugins/jack/JackLibrary.cpp
new file mode 100644
index 00000000000..92462a34cca
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackLibrary.cpp
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#define JACK_LIBRARY_IMPLEMENTATION
+
+#include <string>
+#include <array>
+
+#include "JackLibrary.h"
+
+#ifdef DYNLOAD_JACK
+#include "plugin/PluginManager.h"
+#endif
+
+AUD_NAMESPACE_BEGIN
+
+bool loadJACK()
+{
+#ifdef DYNLOAD_JACK
+ std::array<const std::string, 5> names = {"libjack.so", "libjack.so.0", "libjack.so.1", "libjack.so.2", "libjack.dll"};
+
+ void* handle = nullptr;
+
+ for(auto& name : names)
+ {
+ handle = PluginManager::openLibrary(name);
+ if(handle)
+ break;
+ }
+
+ if (!handle)
+ return false;
+
+#define JACK_SYMBOL(sym) AUD_##sym = reinterpret_cast<decltype(&sym)>(PluginManager::lookupLibrary(handle, #sym))
+#else
+#define JACK_SYMBOL(sym) AUD_##sym = &sym
+#endif
+
+#include "JackSymbols.h"
+
+#undef JACK_SYMBOL
+
+ return AUD_jack_client_open != nullptr;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackLibrary.h b/extern/audaspace/plugins/jack/JackLibrary.h
new file mode 100644
index 00000000000..4e210852702
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackLibrary.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file JackDevice.h
+ * @ingroup plugin
+ * The JackDevice class.
+ */
+
+#include "Audaspace.h"
+
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
+
+AUD_NAMESPACE_BEGIN
+
+#ifdef JACK_LIBRARY_IMPLEMENTATION
+#define JACK_SYMBOL(sym) decltype(&sym) AUD_##sym
+#else
+#define JACK_SYMBOL(sym) extern decltype(&sym) AUD_##sym
+#endif
+
+#include "JackSymbols.h"
+
+#undef JACK_SYMBOL
+
+bool loadJACK();
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackSymbols.h b/extern/audaspace/plugins/jack/JackSymbols.h
new file mode 100644
index 00000000000..f8e22a7da34
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSymbols.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+JACK_SYMBOL(jack_transport_query);
+JACK_SYMBOL(jack_transport_locate);
+
+JACK_SYMBOL(jack_transport_start);
+JACK_SYMBOL(jack_transport_stop);
+
+JACK_SYMBOL(jack_ringbuffer_reset);
+JACK_SYMBOL(jack_ringbuffer_write);
+JACK_SYMBOL(jack_ringbuffer_write_space);
+JACK_SYMBOL(jack_ringbuffer_write_advance);
+JACK_SYMBOL(jack_ringbuffer_read);
+JACK_SYMBOL(jack_ringbuffer_create);
+JACK_SYMBOL(jack_ringbuffer_free);
+JACK_SYMBOL(jack_ringbuffer_read_space);
+JACK_SYMBOL(jack_set_sync_callback);
+
+JACK_SYMBOL(jack_port_get_buffer);
+
+JACK_SYMBOL(jack_client_open);
+JACK_SYMBOL(jack_set_process_callback);
+JACK_SYMBOL(jack_on_shutdown);
+JACK_SYMBOL(jack_port_register);
+JACK_SYMBOL(jack_client_close);
+JACK_SYMBOL(jack_get_sample_rate);
+JACK_SYMBOL(jack_activate);
+JACK_SYMBOL(jack_get_ports);
+JACK_SYMBOL(jack_port_name);
+JACK_SYMBOL(jack_connect);
+JACK_SYMBOL(jack_free);
diff --git a/extern/audaspace/plugins/jack/JackSynchronizer.cpp b/extern/audaspace/plugins/jack/JackSynchronizer.cpp
new file mode 100644
index 00000000000..cd4c448786d
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSynchronizer.cpp
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "JackSynchronizer.h"
+
+#include "JackDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+JackSynchronizer::JackSynchronizer(JackDevice* device) :
+ m_device(device)
+{
+}
+
+void JackSynchronizer::seek(std::shared_ptr<IHandle> handle, float time)
+{
+ m_device->seekPlayback(time);
+}
+
+float JackSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
+{
+ return m_device->getPlaybackPosition();
+}
+
+void JackSynchronizer::play()
+{
+ m_device->startPlayback();
+}
+
+void JackSynchronizer::stop()
+{
+ m_device->stopPlayback();
+}
+
+void JackSynchronizer::setSyncCallback(ISynchronizer::syncFunction function, void* data)
+{
+ m_device->setSyncCallback(function, data);
+}
+
+int JackSynchronizer::isPlaying()
+{
+ return m_device->doesPlayback();
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackSynchronizer.h b/extern/audaspace/plugins/jack/JackSynchronizer.h
new file mode 100644
index 00000000000..5c7341a7872
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSynchronizer.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file JackSynchronizer.h
+ * @ingroup plugin
+ * The JackSynchronizer class.
+ */
+
+#include "devices/ISynchronizer.h"
+
+AUD_NAMESPACE_BEGIN
+
+class JackDevice;
+
+/**
+ * This class is a Synchronizer implementation using JACK Transport.
+ */
+class AUD_PLUGIN_API JackSynchronizer : public ISynchronizer
+{
+private:
+ /// The device that is being synchronized.
+ JackDevice* m_device;
+
+public:
+ /**
+ * Creates a new JackSynchronizer.
+ * @param device The device that should be synchronized.
+ */
+ JackSynchronizer(JackDevice* device);
+
+ virtual void seek(std::shared_ptr<IHandle> handle, float time);
+ virtual float getPosition(std::shared_ptr<IHandle> handle);
+ virtual void play();
+ virtual void stop();
+ virtual void setSyncCallback(syncFunction function, void* data);
+ virtual int isPlaying();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFile.cpp b/extern/audaspace/plugins/libsndfile/SndFile.cpp
new file mode 100644
index 00000000000..ba4ff24ad68
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFile.cpp
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "SndFile.h"
+#include "SndFileReader.h"
+#include "SndFileWriter.h"
+#include "file/FileManager.h"
+
+AUD_NAMESPACE_BEGIN
+
+SndFile::SndFile()
+{
+}
+
+void SndFile::registerPlugin()
+{
+ std::shared_ptr<SndFile> plugin = std::shared_ptr<SndFile>(new SndFile);
+ FileManager::registerInput(plugin);
+ FileManager::registerOutput(plugin);
+}
+
+std::shared_ptr<IReader> SndFile::createReader(std::string filename)
+{
+ return std::shared_ptr<IReader>(new SndFileReader(filename));
+}
+
+std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer)
+{
+ return std::shared_ptr<IReader>(new SndFileReader(buffer));
+}
+
+std::shared_ptr<IWriter> SndFile::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return std::shared_ptr<IWriter>(new SndFileWriter(filename, specs, format, codec, bitrate));
+}
+
+#ifdef LIBSNDFILE_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ SndFile::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "LibSndFile";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFile.h b/extern/audaspace/plugins/libsndfile/SndFile.h
new file mode 100644
index 00000000000..61afed1d564
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFile.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFile.h
+ * @ingroup plugin
+ * The SndFile class.
+ */
+
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This plugin class reads and writes sounds via libsndfile.
+ */
+class AUD_PLUGIN_API SndFile : public IFileInput, public IFileOutput
+{
+private:
+ // delete copy constructor and operator=
+ SndFile(const SndFile&) = delete;
+ SndFile& operator=(const SndFile&) = delete;
+
+public:
+ /**
+ * Creates a new libsndfile plugin.
+ */
+ SndFile();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+
+ virtual std::shared_ptr<IReader> createReader(std::string filename);
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.cpp b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp
new file mode 100644
index 00000000000..d2d89814c07
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "SndFileReader.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+sf_count_t SndFileReader::vio_get_filelen(void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+ return reader->m_membuffer->getSize();
+}
+
+sf_count_t SndFileReader::vio_seek(sf_count_t offset, int whence,
+ void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_memoffset = offset;
+ break;
+ case SEEK_CUR:
+ reader->m_memoffset = reader->m_memoffset + offset;
+ break;
+ case SEEK_END:
+ reader->m_memoffset = reader->m_membuffer->getSize() + offset;
+ break;
+ }
+
+ return reader->m_memoffset;
+}
+
+sf_count_t SndFileReader::vio_read(void* ptr, sf_count_t count,
+ void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ if(reader->m_memoffset + count > reader->m_membuffer->getSize())
+ count = reader->m_membuffer->getSize() - reader->m_memoffset;
+
+ std::memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
+ reader->m_memoffset, count);
+ reader->m_memoffset += count;
+
+ return count;
+}
+
+sf_count_t SndFileReader::vio_tell(void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ return reader->m_memoffset;
+}
+
+SndFileReader::SndFileReader(std::string filename) :
+ m_position(0)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The file couldn't be opened with libsndfile.");
+
+ m_specs.channels = (Channels) sfinfo.channels;
+ m_specs.rate = (SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+}
+
+SndFileReader::SndFileReader(std::shared_ptr<Buffer> buffer) :
+ m_position(0),
+ m_membuffer(buffer),
+ m_memoffset(0)
+{
+ m_vio.get_filelen = vio_get_filelen;
+ m_vio.read = vio_read;
+ m_vio.seek = vio_seek;
+ m_vio.tell = vio_tell;
+ m_vio.write = nullptr;
+
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The buffer couldn't be read with libsndfile.");
+
+ m_specs.channels = (Channels) sfinfo.channels;
+ m_specs.rate = (SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+}
+
+SndFileReader::~SndFileReader()
+{
+ sf_close(m_sndfile);
+}
+
+bool SndFileReader::isSeekable() const
+{
+ return m_seekable;
+}
+
+void SndFileReader::seek(int position)
+{
+ if(m_seekable)
+ {
+ position = sf_seek(m_sndfile, position, SEEK_SET);
+ m_position = position;
+ }
+}
+
+int SndFileReader::getLength() const
+{
+ return m_length;
+}
+
+int SndFileReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SndFileReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void SndFileReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int olen = length;
+
+ length = sf_readf_float(m_sndfile, buffer, length);
+
+ m_position += length;
+
+ eos = length < olen;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.h b/extern/audaspace/plugins/libsndfile/SndFileReader.h
new file mode 100644
index 00000000000..081c29c686c
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileReader.h
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#include "IReader.h"
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFileReader.h
+ * @ingroup plugin
+ * The SndFileReader class.
+ */
+
+#include <string>
+#include <sndfile.h>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This class reads a sound file via libsndfile.
+ */
+class AUD_PLUGIN_API SndFileReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The sample count in the file.
+ */
+ int m_length;
+
+ /**
+ * Whether the file is seekable.
+ */
+ bool m_seekable;
+
+ /**
+ * The specification of the audio data.
+ */
+ Specs m_specs;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ /**
+ * The virtual IO structure for memory file reading.
+ */
+ SF_VIRTUAL_IO m_vio;
+
+ /**
+ * The pointer to the memory file.
+ */
+ std::shared_ptr<Buffer> m_membuffer;
+
+ /**
+ * The current reading pointer of the memory file.
+ */
+ int m_memoffset;
+
+ // Functions for libsndfile virtual IO functionality
+ AUD_LOCAL static sf_count_t vio_get_filelen(void* user_data);
+ AUD_LOCAL static sf_count_t vio_seek(sf_count_t offset, int whence, void* user_data);
+ AUD_LOCAL static sf_count_t vio_read(void* ptr, sf_count_t count, void* user_data);
+ AUD_LOCAL static sf_count_t vio_tell(void* user_data);
+
+ // delete copy constructor and operator=
+ SndFileReader(const SndFileReader&) = delete;
+ SndFileReader& operator=(const SndFileReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param filename The path to the file to be read.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with libsndfile.
+ */
+ SndFileReader(std::string filename);
+
+ /**
+ * Creates a new reader.
+ * \param buffer The buffer to read from.
+ * \exception Exception Thrown if the buffer specified cannot be read
+ * with libsndfile.
+ */
+ SndFileReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~SndFileReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp
new file mode 100644
index 00000000000..d2ab117132d
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "SndFileWriter.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SndFileWriter::SndFileWriter(std::string filename, DeviceSpecs specs,
+ Container format, Codec codec, unsigned int bitrate) :
+ m_position(0), m_specs(specs)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.channels = specs.channels;
+ sfinfo.samplerate = int(specs.rate);
+
+ switch(format)
+ {
+ case CONTAINER_FLAC:
+ sfinfo.format = SF_FORMAT_FLAC;
+ switch(specs.format)
+ {
+ case FORMAT_S16:
+ sfinfo.format |= SF_FORMAT_PCM_16;
+ break;
+ case FORMAT_S24:
+ sfinfo.format |= SF_FORMAT_PCM_24;
+ break;
+ case FORMAT_S32:
+ sfinfo.format |= SF_FORMAT_PCM_32;
+ break;
+ case FORMAT_FLOAT32:
+ sfinfo.format |= SF_FORMAT_FLOAT;
+ break;
+ case FORMAT_FLOAT64:
+ sfinfo.format |= SF_FORMAT_DOUBLE;
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+ break;
+ case CONTAINER_OGG:
+ if(codec == CODEC_VORBIS)
+ sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
+ else
+ sfinfo.format = 0;
+ break;
+ case CONTAINER_WAV:
+ sfinfo.format = SF_FORMAT_WAV;
+ switch(specs.format)
+ {
+ case FORMAT_U8:
+ sfinfo.format |= SF_FORMAT_PCM_U8;
+ break;
+ case FORMAT_S16:
+ sfinfo.format |= SF_FORMAT_PCM_16;
+ break;
+ case FORMAT_S24:
+ sfinfo.format |= SF_FORMAT_PCM_24;
+ break;
+ case FORMAT_S32:
+ sfinfo.format |= SF_FORMAT_PCM_32;
+ break;
+ case FORMAT_FLOAT32:
+ sfinfo.format |= SF_FORMAT_FLOAT;
+ break;
+ case FORMAT_FLOAT64:
+ sfinfo.format |= SF_FORMAT_DOUBLE;
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+
+ if(sfinfo.format == 0)
+ AUD_THROW(FileException, "This format couldn't be written with libsndfile.");
+
+ m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The file couldn't be written with libsndfile.");
+}
+
+SndFileWriter::~SndFileWriter()
+{
+ sf_close(m_sndfile);
+}
+
+int SndFileWriter::getPosition() const
+{
+ return m_position;
+}
+
+DeviceSpecs SndFileWriter::getSpecs() const
+{
+ return m_specs;
+}
+
+void SndFileWriter::write(unsigned int length, sample_t* buffer)
+{
+ length = sf_writef_float(m_sndfile, buffer, length);
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.h b/extern/audaspace/plugins/libsndfile/SndFileWriter.h
new file mode 100644
index 00000000000..75d761f5163
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.h
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFileWriter.h
+ * @ingroup plugin
+ * The SndFileWriter class.
+ */
+
+#include "file/IWriter.h"
+
+#include <string>
+#include <sndfile.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class writes a sound file via libsndfile.
+ */
+class AUD_PLUGIN_API SndFileWriter : public IWriter
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ // delete copy constructor and operator=
+ SndFileWriter(const SndFileWriter&) = delete;
+ SndFileWriter& operator=(const SndFileWriter&) = delete;
+
+public:
+ /**
+ * Creates a new writer.
+ * \param filename The path to the file to be read.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified cannot be written
+ * with libsndfile.
+ */
+ SndFileWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Destroys the writer and closes the file.
+ */
+ virtual ~SndFileWriter();
+
+ virtual int getPosition() const;
+ virtual DeviceSpecs getSpecs() const;
+ virtual void write(unsigned int length, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALDevice.cpp b/extern/audaspace/plugins/openal/OpenALDevice.cpp
new file mode 100644
index 00000000000..2a609789a6d
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALDevice.cpp
@@ -0,0 +1,1490 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "OpenALDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "respec/ConverterReader.h"
+#include "Exception.h"
+#include "ISound.h"
+
+#include <chrono>
+#include <cstring>
+#include <iostream>
+
+AUD_NAMESPACE_BEGIN
+
+/******************************************************************************/
+/*********************** OpenALHandle Handle Code *************************/
+/******************************************************************************/
+
+bool OpenALDevice::OpenALHandle::pause(bool keep)
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PLAYING)
+ {
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
+
+ alSourcePause(m_source);
+
+ m_status = keep ? STATUS_STOPPED : STATUS_PAUSED;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+OpenALDevice::OpenALHandle::OpenALHandle(OpenALDevice* device, ALenum format, std::shared_ptr<IReader> reader, bool keep) :
+ m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format),
+ m_eos(false), m_loopcount(0), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING),
+ m_device(device)
+{
+ DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+
+ // OpenAL playback code
+ alGenBuffers(CYCLE_BUFFERS, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Buffer generation failed while staring playback with OpenAL.");
+
+ try
+ {
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+ int length;
+ bool eos;
+
+ for(m_current = 0; m_current < CYCLE_BUFFERS; m_current++)
+ {
+ length = m_device->m_buffersize;
+ reader->read(length, eos, m_device->m_buffer.getBuffer());
+
+ if(length == 0)
+ break;
+
+ alBufferData(m_buffers[m_current], m_format, m_device->m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Filling the buffer with data failed while starting playback with OpenAL.");
+ }
+
+ alGenSources(1, &m_source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Source generation failed while starting playback with OpenAL.");
+
+ try
+ {
+ alSourceQueueBuffers(m_source, m_current, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Buffer queuing failed while starting playback with OpenAL.");
+ }
+ catch(Exception&)
+ {
+ alDeleteSources(1, &m_source);
+ throw;
+ }
+ }
+ catch(Exception&)
+ {
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+ throw;
+ }
+ alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
+}
+
+bool OpenALDevice::OpenALHandle::pause()
+{
+ return pause(false);
+}
+
+bool OpenALDevice::OpenALHandle::resume()
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PAUSED)
+ {
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+ m_device->m_playingSounds.push_back(This);
+
+ m_device->start();
+ m_status = STATUS_PLAYING;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_status = STATUS_INVALID;
+
+ alDeleteSources(1, &m_source);
+ if(!m_isBuffered)
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_keep = keep;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(m_isBuffered)
+ alSourcef(m_source, AL_SEC_OFFSET, position);
+ else
+ {
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+ m_eos = false;
+
+ ALint info;
+
+ alGetSourcei(m_source, AL_SOURCE_STATE, &info);
+
+ // we need to stop playing sounds as well to clear the buffers
+ // this might cause clicks, but fixes a bug regarding position determination
+ if(info == AL_PAUSED || info == AL_PLAYING)
+ alSourceStop(m_source);
+
+ alSourcei(m_source, AL_BUFFER, 0);
+
+ ALenum err;
+ if((err = alGetError()) == AL_NO_ERROR)
+ {
+ int length;
+ DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ for(m_current = 0; m_current < CYCLE_BUFFERS; m_current++)
+ {
+ length = m_device->m_buffersize;
+
+ m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
+
+ if(length == 0)
+ break;
+
+ alBufferData(m_buffers[m_current], m_format, m_device->m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ if(m_loopcount != 0)
+ m_eos = false;
+
+ alSourceQueueBuffers(m_source, m_current, m_buffers);
+ }
+
+ alSourceRewind(m_source);
+ }
+
+ if(m_status == STATUS_STOPPED)
+ m_status = STATUS_PAUSED;
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getPosition()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return 0.0f;
+
+ float position = 0.0f;
+
+ alGetSourcef(m_source, AL_SEC_OFFSET, &position);
+
+ if(!m_isBuffered)
+ {
+ int queued;
+
+ // this usually always returns CYCLE_BUFFERS
+ alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queued);
+
+ Specs specs = m_reader->getSpecs();
+ position += (m_reader->getPosition() - m_device->m_buffersize * queued) / (float)specs.rate;
+ }
+
+ return position;
+}
+
+Status OpenALDevice::OpenALHandle::getStatus()
+{
+ return m_status;
+}
+
+float OpenALDevice::OpenALHandle::getVolume()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f)
+ alSourcef(m_source, AL_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getPitch()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_PITCH, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(pitch > 0.0f)
+ alSourcef(m_source, AL_PITCH, pitch);
+
+ return true;
+}
+
+int OpenALDevice::OpenALHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool OpenALDevice::OpenALHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+
+ if(m_status == STATUS_STOPPED && (count > m_loopcount || count < 0))
+ m_status = STATUS_PAUSED;
+
+ m_loopcount = count;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ return true;
+}
+
+/******************************************************************************/
+/********************* OpenALHandle 3DHandle Code *************************/
+/******************************************************************************/
+
+Vector3 OpenALDevice::OpenALHandle::getLocation()
+{
+ Vector3 result = Vector3(0, 0, 0);
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ ALfloat p[3];
+ alGetSourcefv(m_source, AL_POSITION, p);
+
+ result = Vector3(p[0], p[1], p[2]);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setLocation(const Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+
+ return true;
+}
+
+Vector3 OpenALDevice::OpenALHandle::getVelocity()
+{
+ Vector3 result = Vector3(0, 0, 0);
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ ALfloat v[3];
+ alGetSourcefv(m_source, AL_VELOCITY, v);
+
+ result = Vector3(v[0], v[1], v[2]);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVelocity(const Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+
+ return true;
+}
+
+Quaternion OpenALDevice::OpenALHandle::getOrientation()
+{
+ return m_orientation;
+}
+
+bool OpenALDevice::OpenALHandle::setOrientation(const Quaternion& orientation)
+{
+ 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;
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_DIRECTION, direction);
+
+ m_orientation = orientation;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::isRelative()
+{
+ int result;
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getVolumeMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MAX_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_MAX_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getVolumeMinimum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MIN_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_MIN_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getDistanceMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(distance >= 0.0f)
+ alSourcef(m_source, AL_MAX_DISTANCE, distance);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getDistanceReference()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(distance >= 0.0f)
+ alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getAttenuation()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(factor >= 0.0f)
+ alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeAngleOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeAngleInner()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeVolumeOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+
+ return true;
+}
+
+/******************************************************************************/
+/**************************** Threading Code **********************************/
+/******************************************************************************/
+
+void OpenALDevice::start()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(!m_playing)
+ {
+ if(m_thread.joinable())
+ m_thread.join();
+
+ m_thread = std::thread(&OpenALDevice::updateStreams, this);
+
+ m_playing = true;
+ }
+}
+
+void OpenALDevice::updateStreams()
+{
+ int length;
+
+ ALint info;
+ DeviceSpecs specs = m_specs;
+ ALCenum cerr;
+ std::list<std::shared_ptr<OpenALHandle> > stopSounds;
+ std::list<std::shared_ptr<OpenALHandle> > pauseSounds;
+
+ auto sleepDuration = std::chrono::milliseconds(20);
+
+ for(;;)
+ {
+ lock();
+
+ alcSuspendContext(m_context);
+ cerr = alcGetError(m_device);
+ if(cerr == ALC_NO_ERROR)
+ {
+ // for all sounds
+ for(auto& sound : m_playingSounds)
+ {
+ // is it a streamed sound?
+ if(!sound->m_isBuffered)
+ {
+ // check for buffer refilling
+ alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
+
+ info += (OpenALHandle::CYCLE_BUFFERS - sound->m_current);
+
+ if(info)
+ {
+ specs.specs = sound->m_reader->getSpecs();
+ m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ // for all empty buffers
+ while(info--)
+ {
+ // if there's still data to play back
+ if(!sound->m_eos)
+ {
+ // read data
+ length = m_buffersize;
+
+ try
+ {
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
+
+ // looping necessary?
+ if(length == 0 && sound->m_loopcount)
+ {
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
+
+ sound->m_reader->seek(0);
+
+ length = m_buffersize;
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
+ }
+ }
+ catch(Exception& e)
+ {
+ length = 0;
+ std::cerr << "Caught exception while reading sound data during playback with OpenAL: " << e.getMessage() << std::endl;
+ }
+
+ if(sound->m_loopcount != 0)
+ sound->m_eos = false;
+
+ // read nothing?
+ if(length == 0)
+ {
+ break;
+ }
+
+ ALuint buffer;
+
+ if(sound->m_current < OpenALHandle::CYCLE_BUFFERS)
+ buffer = sound->m_buffers[sound->m_current++];
+ else
+ alSourceUnqueueBuffers(sound->m_source, 1, &buffer);
+
+ ALenum err;
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+
+ // fill with new data
+ alBufferData(buffer, sound->m_format, m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+
+ // and queue again
+ alSourceQueueBuffers(sound->m_source, 1,&buffer);
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ // check if the sound has been stopped
+ alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ // if it really stopped
+ if(sound->m_eos && info != AL_INITIAL)
+ {
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
+
+ // pause or
+ if(sound->m_keep)
+ pauseSounds.push_back(sound);
+ // stop
+ else
+ stopSounds.push_back(sound);
+ }
+ // continue playing
+ else
+ alSourcePlay(sound->m_source);
+ }
+ }
+
+ for(auto& sound : pauseSounds)
+ sound->pause(true);
+
+ for(auto& sound : stopSounds)
+ sound->stop();
+
+ pauseSounds.clear();
+ stopSounds.clear();
+
+ alcProcessContext(m_context);
+ }
+
+ // stop thread
+ if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
+ {
+ m_playing = false;
+ unlock();
+
+ return;
+ }
+
+ unlock();
+
+ std::this_thread::sleep_for(sleepDuration);
+ }
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name) :
+ m_playing(false), m_buffersize(buffersize)
+{
+ // cannot determine how many channels or which format OpenAL uses, but
+ // it at least is able to play 16 bit stereo audio
+ specs.format = FORMAT_S16;
+
+ if(name.empty())
+ m_device = alcOpenDevice(nullptr);
+ else
+ m_device = alcOpenDevice(name.c_str());
+
+ if(!m_device)
+ AUD_THROW(DeviceException, "The audio device couldn't be opened with OpenAL.");
+
+ // at least try to set the frequency
+ ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 };
+ ALCint* attributes = attribs;
+ if(specs.rate == RATE_INVALID)
+ attributes = nullptr;
+
+ 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 = FORMAT_FLOAT32;
+
+ m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
+
+ if((!m_useMC && specs.channels > CHANNELS_STEREO) ||
+ specs.channels == CHANNELS_STEREO_LFE ||
+ specs.channels == CHANNELS_SURROUND5)
+ specs.channels = CHANNELS_STEREO;
+
+ alGetError();
+ alcGetError(m_device);
+
+ m_specs = specs;
+}
+
+OpenALDevice::~OpenALDevice()
+{
+ lock();
+ alcSuspendContext(m_context);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ alcProcessContext(m_context);
+
+ // wait for the thread to stop
+ unlock();
+ if(m_thread.joinable())
+ m_thread.join();
+
+ // quit OpenAL
+ alcMakeContextCurrent(nullptr);
+ alcDestroyContext(m_context);
+ alcCloseDevice(m_device);
+}
+
+DeviceSpecs OpenALDevice::getSpecs() const
+{
+ return m_specs;
+}
+
+bool OpenALDevice::getFormat(ALenum &format, Specs specs)
+{
+ bool valid = true;
+ format = 0;
+
+ switch(m_specs.format)
+ {
+ case FORMAT_S16:
+ switch(specs.channels)
+ {
+ case CHANNELS_MONO:
+ format = AL_FORMAT_MONO16;
+ break;
+ case CHANNELS_STEREO:
+ format = AL_FORMAT_STEREO16;
+ break;
+ case CHANNELS_SURROUND4:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_QUAD16");
+ break;
+ }
+ case CHANNELS_SURROUND51:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_51CHN16");
+ break;
+ }
+ case CHANNELS_SURROUND61:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_61CHN16");
+ break;
+ }
+ case CHANNELS_SURROUND71:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_71CHN16");
+ break;
+ }
+ default:
+ valid = false;
+ }
+ break;
+ case FORMAT_FLOAT32:
+ switch(specs.channels)
+ {
+ case CHANNELS_MONO:
+ format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
+ break;
+ case CHANNELS_STEREO:
+ format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
+ break;
+ case CHANNELS_SURROUND4:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_QUAD32");
+ break;
+ }
+ case CHANNELS_SURROUND51:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_51CHN32");
+ break;
+ }
+ case CHANNELS_SURROUND61:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_61CHN32");
+ break;
+ }
+ case CHANNELS_SURROUND71:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_71CHN32");
+ break;
+ }
+ default:
+ valid = false;
+ }
+ break;
+ default:
+ valid = false;
+ }
+
+ if(!format)
+ valid = false;
+
+ return valid;
+}
+
+std::shared_ptr<IHandle> OpenALDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ Specs specs = reader->getSpecs();
+
+ // check format
+ if(specs.channels == CHANNELS_INVALID)
+ return std::shared_ptr<IHandle>();
+
+ if(m_specs.format != FORMAT_FLOAT32)
+ reader = std::shared_ptr<IReader>(new ConverterReader(reader, m_specs));
+
+ ALenum format;
+
+ if(!getFormat(format, specs))
+ return std::shared_ptr<IHandle>();
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alcSuspendContext(m_context);
+
+ std::shared_ptr<OpenALDevice::OpenALHandle> sound;
+
+ try
+ {
+ // create the handle
+ sound = std::shared_ptr<OpenALDevice::OpenALHandle>(new OpenALDevice::OpenALHandle(this, format, reader, keep));
+ }
+ catch(Exception&)
+ {
+ alcProcessContext(m_context);
+ throw;
+ }
+
+ alcProcessContext(m_context);
+
+ // play sound
+ m_playingSounds.push_back(sound);
+
+ start();
+
+ return std::shared_ptr<IHandle>(sound);
+}
+
+std::shared_ptr<IHandle> OpenALDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return play(sound->createReader(), keep);
+}
+
+void OpenALDevice::stopAll()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alcSuspendContext(m_context);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ alcProcessContext(m_context);
+}
+
+void OpenALDevice::lock()
+{
+ m_mutex.lock();
+}
+
+void OpenALDevice::unlock()
+{
+ m_mutex.unlock();
+}
+
+float OpenALDevice::getVolume() const
+{
+ float result;
+
+ alGetListenerf(AL_GAIN, &result);
+ return result;
+}
+
+void OpenALDevice::setVolume(float volume)
+{
+ if(volume < 0.0f)
+ return;
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerf(AL_GAIN, volume);
+}
+
+ISynchronizer* OpenALDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+Vector3 OpenALDevice::getListenerLocation() const
+{
+ ALfloat p[3];
+
+ alGetListenerfv(AL_POSITION, p);
+ return Vector3(p[0], p[1], p[2]);
+}
+
+void OpenALDevice::setListenerLocation(const Vector3& location)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerfv(AL_POSITION, (ALfloat*)location.get());
+}
+
+Vector3 OpenALDevice::getListenerVelocity() const
+{
+ ALfloat v[3];
+
+ alGetListenerfv(AL_VELOCITY, v);
+ return Vector3(v[0], v[1], v[2]);
+}
+
+void OpenALDevice::setListenerVelocity(const Vector3& velocity)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
+}
+
+Quaternion OpenALDevice::getListenerOrientation() const
+{
+ return m_orientation;
+}
+
+void OpenALDevice::setListenerOrientation(const Quaternion& orientation)
+{
+ ALfloat direction[6];
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ 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);
+ m_orientation = orientation;
+}
+
+float OpenALDevice::getSpeedOfSound() const
+{
+ return alGetFloat(AL_SPEED_OF_SOUND);
+}
+
+void OpenALDevice::setSpeedOfSound(float speed)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alSpeedOfSound(speed);
+}
+
+float OpenALDevice::getDopplerFactor() const
+{
+ return alGetFloat(AL_DOPPLER_FACTOR);
+}
+
+void OpenALDevice::setDopplerFactor(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alDopplerFactor(factor);
+}
+
+DistanceModel OpenALDevice::getDistanceModel() const
+{
+ switch(alGetInteger(AL_DISTANCE_MODEL))
+ {
+ case AL_INVERSE_DISTANCE:
+ return DISTANCE_MODEL_INVERSE;
+ case AL_INVERSE_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_INVERSE_CLAMPED;
+ case AL_LINEAR_DISTANCE:
+ return DISTANCE_MODEL_LINEAR;
+ case AL_LINEAR_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_LINEAR_CLAMPED;
+ case AL_EXPONENT_DISTANCE:
+ return DISTANCE_MODEL_EXPONENT;
+ case AL_EXPONENT_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_EXPONENT_CLAMPED;
+ default:
+ return DISTANCE_MODEL_INVALID;
+ }
+}
+
+void OpenALDevice::setDistanceModel(DistanceModel model)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ switch(model)
+ {
+ case DISTANCE_MODEL_INVERSE:
+ alDistanceModel(AL_INVERSE_DISTANCE);
+ break;
+ case DISTANCE_MODEL_INVERSE_CLAMPED:
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+ break;
+ case DISTANCE_MODEL_LINEAR:
+ alDistanceModel(AL_LINEAR_DISTANCE);
+ break;
+ case DISTANCE_MODEL_LINEAR_CLAMPED:
+ alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+ break;
+ case DISTANCE_MODEL_EXPONENT:
+ alDistanceModel(AL_EXPONENT_DISTANCE);
+ break;
+ case DISTANCE_MODEL_EXPONENT_CLAMPED:
+ alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+ break;
+ default:
+ alDistanceModel(AL_NONE);
+ }
+}
+
+std::list<std::string> OpenALDevice::getDeviceNames()
+{
+ std::list<std::string> names;
+
+ if(alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT") == AL_TRUE)
+ {
+ ALCchar* devices = const_cast<ALCchar*>(alcGetString(nullptr, ALC_DEVICE_SPECIFIER));
+ std::string default_device = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
+
+ while(*devices)
+ {
+ std::string device = devices;
+
+ if(device == default_device)
+ names.push_front(device);
+ else
+ names.push_back(device);
+
+ devices += strlen(devices) + 1;
+ }
+ }
+
+ return names;
+}
+
+class OpenALDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+ std::string m_name;
+
+public:
+ OpenALDeviceFactory(std::string name = "") :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE),
+ m_name(name)
+ {
+ m_specs.format = FORMAT_FLOAT32;
+ m_specs.channels = CHANNELS_SURROUND51;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new OpenALDevice(m_specs, m_buffersize, m_name));
+ }
+
+ virtual int getPriority()
+ {
+ return 1 << 10;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void OpenALDevice::registerPlugin()
+{
+ auto names = OpenALDevice::getDeviceNames();
+ DeviceManager::registerDevice("OpenAL", std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory));
+ for(std::string &name : names)
+ {
+ DeviceManager::registerDevice("OpenAL - " + name, std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory(name)));
+ }
+}
+
+#ifdef OPENAL_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ OpenALDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "OpenAL";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/extern/audaspace/plugins/openal/OpenALDevice.h
index f0e47824967..b9b461a327c 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/extern/audaspace/plugins/openal/OpenALDevice.h
@@ -1,64 +1,66 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/OpenAL/AUD_OpenALDevice.h
- * \ingroup audopenal
- */
+#pragma once
+#ifdef OPENAL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
-#ifndef __AUD_OPENALDEVICE_H__
-#define __AUD_OPENALDEVICE_H__
+/**
+ * @file OpenALDevice.h
+ * @ingroup plugin
+ * The OpenALDevice class.
+ */
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_Buffer.h"
-//struct AUD_OpenALBufferedFactory;
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "devices/I3DHandle.h"
+#include "devices/DefaultSynchronizer.h"
+#include "util/Buffer.h"
-#include <AL/al.h>
-#include <AL/alc.h>
+#include <al.h>
+#include <alc.h>
#include <list>
-#include <pthread.h>
+#include <mutex>
+#include <thread>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
/**
* This device plays through OpenAL.
*/
-class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
+class AUD_PLUGIN_API OpenALDevice : public IDevice, public I3DDevice
{
private:
/// Saves the data for playback.
- class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
+ class OpenALHandle : public IHandle, public I3DHandle
{
- public:
+ private:
+ friend class OpenALDevice;
+
static const int CYCLE_BUFFERS = 3;
/// Whether it's a buffered or a streamed source.
bool m_isBuffered;
/// The reader source.
- boost::shared_ptr<AUD_IReader> m_reader;
+ std::shared_ptr<IReader> m_reader;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -88,15 +90,19 @@ private:
void* m_stop_data;
/// Orientation.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Current status of the handle
- AUD_Status m_status;
+ Status m_status;
/// Own device.
- AUD_OpenALDevice* m_device;
+ OpenALDevice* m_device;
- bool pause(bool keep);
+ AUD_LOCAL bool pause(bool keep);
+
+ // delete copy constructor and operator=
+ OpenALHandle(const OpenALHandle&) = delete;
+ OpenALHandle& operator=(const OpenALHandle&) = delete;
public:
@@ -107,9 +113,9 @@ private:
* \param reader The reader this handle plays.
* \param keep Whether to keep the handle alive when the reader ends.
*/
- AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep);
+ OpenALHandle(OpenALDevice* device, ALenum format, std::shared_ptr<IReader> reader, bool keep);
- virtual ~AUD_OpenALHandle() {}
+ virtual ~OpenALHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
@@ -117,7 +123,7 @@ private:
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
- virtual AUD_Status getStatus();
+ virtual Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
@@ -126,12 +132,12 @@ private:
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- virtual AUD_Vector3 getSourceLocation();
- virtual bool setSourceLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity();
- virtual bool setSourceVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation();
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual Vector3 getLocation();
+ virtual bool setLocation(const Vector3& location);
+ virtual Vector3 getVelocity();
+ virtual bool setVelocity(const Vector3& velocity);
+ virtual Quaternion getOrientation();
+ virtual bool setOrientation(const Quaternion& orientation);
virtual bool isRelative();
virtual bool setRelative(bool relative);
virtual float getVolumeMaximum();
@@ -152,8 +158,6 @@ private:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<boost::shared_ptr<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
-
/**
* The OpenAL device handle.
*/
@@ -167,7 +171,7 @@ private:
/**
* The specification of the device.
*/
- AUD_DeviceSpecs m_specs;
+ DeviceSpecs m_specs;
/**
* Whether the device has the AL_EXT_MCFORMATS extension.
@@ -177,27 +181,22 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<boost::shared_ptr<AUD_OpenALHandle> > m_playingSounds;
+ std::list<std::shared_ptr<OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<boost::shared_ptr<AUD_OpenALHandle> > m_pausedSounds;
-
- /**
- * The list of buffered factories.
- */
- //std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+ std::list<std::shared_ptr<OpenALHandle> > m_pausedSounds;
/**
* The mutex for locking.
*/
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/**
* The streaming thread.
*/
- pthread_t m_thread;
+ std::thread m_thread;
/**
* The condition for streaming thread wakeup.
@@ -212,18 +211,26 @@ private:
/**
* Device buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* Orientation.
*/
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
+
+ /// Synchronizer.
+ DefaultSynchronizer m_synchronizer;
/**
* Starts the streaming thread.
* \param Whether the previous thread should be joined.
*/
- void start(bool join = true);
+ AUD_LOCAL void start();
+
+ /**
+ * Streaming thread main function.
+ */
+ AUD_LOCAL void updateStreams();
/**
* Gets the format according to the specs.
@@ -231,52 +238,59 @@ private:
* \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);
+ AUD_LOCAL bool getFormat(ALenum &format, Specs specs);
- // hide copy constructor and operator=
- AUD_OpenALDevice(const AUD_OpenALDevice&);
- AUD_OpenALDevice& operator=(const AUD_OpenALDevice&);
+ // delete copy constructor and operator=
+ OpenALDevice(const OpenALDevice&) = delete;
+ OpenALDevice& operator=(const OpenALDevice&) = delete;
public:
/**
* Opens the OpenAL audio device for playback.
* \param specs The wanted audio specification.
* \param buffersize The size of the internal buffer.
+ * \param name The name of the device to be opened.
* \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.
+ * \exception DeviceException Thrown if the audio device cannot be opened.
*/
- void updateStreams();
+ OpenALDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE, std::string name = "");
- virtual ~AUD_OpenALDevice();
+ virtual ~OpenALDevice();
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
+ virtual DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
-
- 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 ISynchronizer* getSynchronizer();
+
+ virtual Vector3 getListenerLocation() const;
+ virtual void setListenerLocation(const Vector3& location);
+ virtual Vector3 getListenerVelocity() const;
+ virtual void setListenerVelocity(const Vector3& velocity);
+ virtual Quaternion getListenerOrientation() const;
+ virtual void setListenerOrientation(const 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 DistanceModel getDistanceModel() const;
+ virtual void setDistanceModel(DistanceModel model);
+
+ /**
+ * Retrieves a list of available hardware devices to open with OpenAL.
+ * @return The list of devices to open.
+ */
+ static std::list<std::string> getDeviceNames();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
};
-#endif //__AUD_OPENALDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALReader.cpp b/extern/audaspace/plugins/openal/OpenALReader.cpp
new file mode 100644
index 00000000000..52356d4f7ec
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALReader.cpp
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "OpenALReader.h"
+#include "respec/ConverterFunctions.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <al.h>
+
+AUD_NAMESPACE_BEGIN
+
+OpenALReader::OpenALReader(Specs specs, int buffersize) :
+ m_specs(specs),
+ m_position(0),
+ m_device(nullptr)
+{
+ if((specs.channels != CHANNELS_MONO) && (specs.channels != CHANNELS_STEREO))
+ specs.channels = CHANNELS_MONO;
+
+ m_device = alcCaptureOpenDevice(nullptr, specs.rate,
+ specs.channels == CHANNELS_MONO ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
+ buffersize * specs.channels * 2);
+
+ if(!m_device)
+ AUD_THROW(DeviceException, "The capture device couldn't be opened with OpenAL.");
+
+ alcCaptureStart(m_device);
+}
+
+OpenALReader::~OpenALReader()
+{
+ if(m_device)
+ {
+ //alcCaptureStop(m_device);
+ alcCaptureCloseDevice(m_device);
+ }
+}
+
+bool OpenALReader::isSeekable() const
+{
+ return false;
+}
+
+void OpenALReader::seek(int position)
+{
+ m_position = position;
+}
+
+int OpenALReader::getLength() const
+{
+ int length;
+ alcGetIntegerv(m_device, ALC_CAPTURE_SAMPLES, 1, &length);
+ return length;
+}
+
+int OpenALReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs OpenALReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void OpenALReader::read(int & length, bool& eos, sample_t* buffer)
+{
+ int len = getLength();
+ length = std::min(length, len);
+
+ if(length > 0)
+ {
+ alcCaptureSamples(m_device, buffer, length);
+ convert_s16_float((data_t*)buffer, (data_t*)buffer, length * m_specs.channels);
+ }
+
+ eos = false;
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALReader.h b/extern/audaspace/plugins/openal/OpenALReader.h
new file mode 100644
index 00000000000..5d96ea9b027
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALReader.h
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef OPENAL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file OpenALReader.h
+ * @ingroup plugin
+ * The OpenALReader class.
+ */
+
+#include "IReader.h"
+
+#include <alc.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sine tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_PLUGIN_API OpenALReader : public IReader
+{
+private:
+ /**
+ * The specs of the reader.
+ */
+ Specs m_specs;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The capture device.
+ */
+ ALCdevice* m_device;
+
+ // delete copy constructor and operator=
+ OpenALReader(const OpenALReader&) = delete;
+ OpenALReader& operator=(const OpenALReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param specs The desired specification of the output samples.
+ * \param buffersize The buffer size used to read from the device.
+ */
+ OpenALReader(Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ virtual ~OpenALReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/sdl/SDLDevice.cpp b/extern/audaspace/plugins/sdl/SDLDevice.cpp
new file mode 100644
index 00000000000..603e16001b8
--- /dev/null
+++ b/extern/audaspace/plugins/sdl/SDLDevice.cpp
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "SDLDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "Exception.h"
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+void SDLDevice::SDL_mix(void* data, Uint8* buffer, int length)
+{
+ SDLDevice* device = (SDLDevice*)data;
+
+ if(!device->m_playback)
+ {
+ SDL_PauseAudio(1);
+
+ std::memset(buffer, 0, length);
+
+ return;
+ }
+
+ device->mix((data_t*)buffer, length / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
+}
+
+void SDLDevice::playing(bool playing)
+{
+ if(!m_playback)
+ SDL_PauseAudio(playing ? 0 : 1);
+
+ m_playback = playing;
+}
+
+SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
+ m_playback(false)
+{
+ if(specs.channels == CHANNELS_INVALID)
+ specs.channels = CHANNELS_STEREO;
+ if(specs.format == FORMAT_INVALID)
+ specs.format = FORMAT_S16;
+ if(specs.rate == RATE_INVALID)
+ specs.rate = RATE_48000;
+
+ m_specs = specs;
+
+ SDL_AudioSpec format, obtained;
+
+ format.freq = m_specs.rate;
+ if(m_specs.format == FORMAT_U8)
+ format.format = AUDIO_U8;
+ else
+ format.format = AUDIO_S16SYS;
+ format.channels = m_specs.channels;
+ format.samples = buffersize;
+ format.callback = SDLDevice::SDL_mix;
+ format.userdata = this;
+
+ if(SDL_OpenAudio(&format, &obtained) != 0)
+ AUD_THROW(DeviceException, "The audio device couldn't be opened with SDL.");
+
+ m_specs.rate = (SampleRate)obtained.freq;
+ m_specs.channels = (Channels)obtained.channels;
+ if(obtained.format == AUDIO_U8)
+ m_specs.format = FORMAT_U8;
+ else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
+ m_specs.format = FORMAT_S16;
+ else
+ {
+ SDL_CloseAudio();
+ AUD_THROW(DeviceException, "The sample format obtained from SDL is not supported.");
+ }
+
+ create();
+}
+
+SDLDevice::~SDLDevice()
+{
+ SDL_PauseAudio(1);
+ SDL_CloseAudio();
+
+ destroy();
+}
+
+class SDLDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+
+public:
+ SDLDeviceFactory() :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE)
+ {
+ m_specs.format = FORMAT_S16;
+ m_specs.channels = CHANNELS_STEREO;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new SDLDevice(m_specs, m_buffersize));
+ }
+
+ virtual int getPriority()
+ {
+ return 1 << 5;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void SDLDevice::registerPlugin()
+{
+ DeviceManager::registerDevice("SDL", std::shared_ptr<IDeviceFactory>(new SDLDeviceFactory));
+}
+
+#ifdef SDL_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ SDLDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "SDL";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/sdl/SDLDevice.h b/extern/audaspace/plugins/sdl/SDLDevice.h
new file mode 100644
index 00000000000..935732bb281
--- /dev/null
+++ b/extern/audaspace/plugins/sdl/SDLDevice.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef SDL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SDLDevice.h
+ * @ingroup plugin
+ * The SDLDevice class.
+ */
+
+#include "devices/SoftwareDevice.h"
+
+#include <SDL.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This device plays back through SDL, the simple direct media layer.
+ */
+class AUD_PLUGIN_API SDLDevice : public SoftwareDevice
+{
+private:
+ /**
+ * Whether there is currently playback.
+ */
+ bool m_playback;
+
+ /**
+ * Mixes the next bytes into the buffer.
+ * \param data The SDL device.
+ * \param buffer The target buffer.
+ * \param length The length in bytes to be filled.
+ */
+ AUD_LOCAL static void SDL_mix(void* data, Uint8* buffer, int length);
+
+ // delete copy constructor and operator=
+ SDLDevice(const SDLDevice&) = delete;
+ SDLDevice& operator=(const SDLDevice&) = delete;
+
+protected:
+ virtual void playing(bool playing);
+
+public:
+ /**
+ * Opens the SDL 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.
+ * \exception Exception Thrown if the audio device cannot be opened.
+ */
+ SDLDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ /**
+ * Closes the SDL audio device.
+ */
+ virtual ~SDLDevice();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/Exception.cpp b/extern/audaspace/src/Exception.cpp
new file mode 100644
index 00000000000..1c31cb29555
--- /dev/null
+++ b/extern/audaspace/src/Exception.cpp
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "Exception.h"
+
+#include <sstream>
+
+AUD_NAMESPACE_BEGIN
+
+Exception::Exception(const Exception& exception) :
+ Exception(exception.m_message, exception.m_file, exception.m_line)
+{
+}
+
+Exception::Exception(std::string message, std::string file, int line) :
+ m_message(message),
+ m_file(file),
+ m_line(line)
+{
+}
+
+Exception::~Exception() AUD_NOEXCEPT
+{
+}
+
+const char* Exception::what() const AUD_NOEXCEPT
+{
+ return m_message.c_str();
+}
+
+std::string Exception::getDebugMessage() const
+{
+ std::stringstream out;
+
+ out << m_message << " File " << m_file << ":" << m_line;
+
+ return out.str();
+}
+
+const std::string& Exception::getMessage() const
+{
+ return m_message;
+}
+
+const std::string& Exception::getFile() const
+{
+ return m_file;
+}
+
+int Exception::getLine() const
+{
+ return m_line;
+}
+
+FileException::FileException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+FileException::FileException(const FileException& exception) :
+ Exception(exception)
+{
+}
+
+FileException::~FileException() AUD_NOEXCEPT
+{
+}
+
+DeviceException::DeviceException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+DeviceException::DeviceException(const DeviceException& exception) :
+ Exception(exception)
+{
+}
+
+DeviceException::~DeviceException() AUD_NOEXCEPT
+{
+}
+
+StateException::StateException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+StateException::StateException(const StateException& exception) :
+ Exception(exception)
+{
+}
+
+StateException::~StateException() AUD_NOEXCEPT
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/DefaultSynchronizer.cpp b/extern/audaspace/src/devices/DefaultSynchronizer.cpp
new file mode 100644
index 00000000000..aa8945dadaa
--- /dev/null
+++ b/extern/audaspace/src/devices/DefaultSynchronizer.cpp
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/DefaultSynchronizer.h"
+#include "devices/IHandle.h"
+
+AUD_NAMESPACE_BEGIN
+
+void DefaultSynchronizer::seek(std::shared_ptr<IHandle> handle, float time)
+{
+ handle->seek(time);
+}
+
+float DefaultSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
+{
+ return handle->getPosition();
+}
+
+void DefaultSynchronizer::play()
+{
+}
+
+void DefaultSynchronizer::stop()
+{
+}
+
+void DefaultSynchronizer::setSyncCallback(ISynchronizer::syncFunction function, void* data)
+{
+}
+
+int DefaultSynchronizer::isPlaying()
+{
+ return -1;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/DeviceManager.cpp b/extern/audaspace/src/devices/DeviceManager.cpp
new file mode 100644
index 00000000000..2ebc3d58c86
--- /dev/null
+++ b/extern/audaspace/src/devices/DeviceManager.cpp
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/IDevice.h"
+#include "devices/I3DDevice.h"
+
+#include <limits>
+#include <string>
+#include <algorithm>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, std::shared_ptr<IDeviceFactory>> DeviceManager::m_factories;
+std::shared_ptr<IDevice> DeviceManager::m_device;
+
+void DeviceManager::registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory)
+{
+ m_factories[name] = factory;
+}
+
+std::shared_ptr<IDeviceFactory> DeviceManager::getDeviceFactory(std::string name)
+{
+ return m_factories[name];
+}
+
+std::shared_ptr<IDeviceFactory> DeviceManager::getDefaultDeviceFactory()
+{
+ int min = std::numeric_limits<int>::min();
+
+ std::shared_ptr<IDeviceFactory> result;
+
+ for(auto factory : m_factories)
+ {
+ if(factory.second->getPriority() >= min)
+ {
+ result = factory.second;
+ min = result->getPriority();
+ }
+ }
+
+ return result;
+}
+
+void DeviceManager::setDevice(std::shared_ptr<IDevice> device)
+{
+ m_device = device;
+}
+
+void DeviceManager::openDevice(std::string name)
+{
+ setDevice(getDeviceFactory(name)->openDevice());
+}
+
+void DeviceManager::openDefaultDevice()
+{
+ setDevice(getDefaultDeviceFactory()->openDevice());
+}
+
+void DeviceManager::releaseDevice()
+{
+ m_device = nullptr;
+}
+
+std::shared_ptr<IDevice> DeviceManager::getDevice()
+{
+ return m_device;
+}
+
+std::shared_ptr<I3DDevice> DeviceManager::get3DDevice()
+{
+ return std::dynamic_pointer_cast<I3DDevice>(m_device);
+}
+
+std::vector<std::string> DeviceManager::getAvailableDeviceNames()
+{
+ struct DeviceNamePriority {
+ std::string name;
+ int priority;
+ };
+
+ std::vector<DeviceNamePriority> devices;
+ devices.reserve(m_factories.size());
+
+ for(const auto& pair : m_factories)
+ devices.push_back({pair.first, pair.second->getPriority()});
+
+ auto sort = [](const DeviceNamePriority& lhs, const DeviceNamePriority& rhs){
+ return lhs.priority > rhs.priority;
+ };
+
+ std::sort(devices.begin(), devices.end(), sort);
+
+ std::vector<std::string> names;
+ names.reserve(devices.size());
+
+ for(const auto& device : devices)
+ names.push_back(device.name);
+
+ return names;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/NULLDevice.cpp b/extern/audaspace/src/devices/NULLDevice.cpp
new file mode 100644
index 00000000000..a82537f43b2
--- /dev/null
+++ b/extern/audaspace/src/devices/NULLDevice.cpp
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/NULLDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+
+#include <limits>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+NULLDevice::NULLHandle::NULLHandle()
+{
+}
+
+bool NULLDevice::NULLHandle::pause()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::resume()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::stop()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::getKeep()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::setKeep(bool keep)
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::seek(float position)
+{
+ return false;
+}
+
+float NULLDevice::NULLHandle::getPosition()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+Status NULLDevice::NULLHandle::getStatus()
+{
+ return STATUS_INVALID;
+}
+
+float NULLDevice::NULLHandle::getVolume()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+bool NULLDevice::NULLHandle::setVolume(float volume)
+{
+ return false;
+}
+
+float NULLDevice::NULLHandle::getPitch()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+bool NULLDevice::NULLHandle::setPitch(float pitch)
+{
+ return false;
+}
+
+int NULLDevice::NULLHandle::getLoopCount()
+{
+ return 0;
+}
+
+bool NULLDevice::NULLHandle::setLoopCount(int count)
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::setStopCallback(stopCallback callback, void* data)
+{
+ return false;
+}
+
+NULLDevice::NULLDevice()
+{
+}
+
+NULLDevice::~NULLDevice()
+{
+}
+
+DeviceSpecs NULLDevice::getSpecs() const
+{
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.format = FORMAT_INVALID;
+ specs.rate = RATE_INVALID;
+ return specs;
+}
+
+std::shared_ptr<IHandle> NULLDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ return std::shared_ptr<IHandle>(new NULLHandle());
+}
+
+std::shared_ptr<IHandle> NULLDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return std::shared_ptr<IHandle>(new NULLHandle());
+}
+
+void NULLDevice::stopAll()
+{
+}
+
+void NULLDevice::lock()
+{
+}
+
+void NULLDevice::unlock()
+{
+}
+
+float NULLDevice::getVolume() const
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+void NULLDevice::setVolume(float volume)
+{
+}
+
+ISynchronizer* NULLDevice::getSynchronizer()
+{
+ return nullptr;
+}
+
+class NULLDeviceFactory : public IDeviceFactory
+{
+public:
+ NULLDeviceFactory()
+ {
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new NULLDevice());
+ }
+
+ virtual int getPriority()
+ {
+ return std::numeric_limits<int>::min();
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void NULLDevice::registerPlugin()
+{
+ DeviceManager::registerDevice("Null", std::shared_ptr<IDeviceFactory>(new NULLDeviceFactory));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/ReadDevice.cpp b/extern/audaspace/src/devices/ReadDevice.cpp
new file mode 100644
index 00000000000..487fee1f59a
--- /dev/null
+++ b/extern/audaspace/src/devices/ReadDevice.cpp
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/ReadDevice.h"
+#include "IReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ReadDevice::ReadDevice(DeviceSpecs specs) :
+ m_playing(false)
+{
+ m_specs = specs;
+
+ create();
+}
+
+ReadDevice::ReadDevice(Specs specs) :
+ m_playing(false)
+{
+ m_specs.specs = specs;
+ m_specs.format = FORMAT_FLOAT32;
+
+ create();
+}
+
+ReadDevice::~ReadDevice()
+{
+ destroy();
+}
+
+bool ReadDevice::read(data_t* buffer, int length)
+{
+ if(m_playing)
+ mix(buffer, length);
+ else
+ if(m_specs.format == FORMAT_U8)
+ std::memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
+ else
+ std::memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
+ return m_playing;
+}
+
+void ReadDevice::changeSpecs(Specs specs)
+{
+ if(!AUD_COMPARE_SPECS(specs, m_specs.specs))
+ setSpecs(specs);
+}
+
+void ReadDevice::playing(bool playing)
+{
+ m_playing = playing;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/SoftwareDevice.cpp b/extern/audaspace/src/devices/SoftwareDevice.cpp
new file mode 100644
index 00000000000..c944b9ed12d
--- /dev/null
+++ b/extern/audaspace/src/devices/SoftwareDevice.cpp
@@ -0,0 +1,989 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "devices/SoftwareDevice.h"
+#include "fx/PitchReader.h"
+#include "respec/ChannelMapperReader.h"
+#include "respec/JOSResampleReader.h"
+#include "respec/LinearResampleReader.h"
+#include "respec/Mixer.h"
+#include "Exception.h"
+#include "ISound.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <iostream>
+#include <limits>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+enum RenderFlags
+{
+ RENDER_DISTANCE = 0x01,
+ RENDER_DOPPLER = 0x02,
+ RENDER_CONE = 0x04,
+ RENDER_VOLUME = 0x08
+};
+
+#define PITCH_MAX 10
+
+/******************************************************************************/
+/********************** SoftwareHandle Handle Code ************************/
+/******************************************************************************/
+
+bool SoftwareDevice::SoftwareHandle::pause(bool keep)
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PLAYING)
+ {
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+
+ m_status = keep ? STATUS_STOPPED : STATUS_PAUSED;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep) :
+ m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_old_volume(0), m_loopcount(0),
+ m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
+ m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
+ m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
+{
+}
+
+void SoftwareDevice::SoftwareHandle::update()
+{
+ int flags = 0;
+
+ m_old_volume = m_volume;
+
+ Vector3 SL;
+ if(m_relative)
+ SL = -m_location;
+ else
+ SL = m_device->m_location - m_location;
+ float distance = SL * SL;
+
+ if(distance > 0)
+ distance = sqrt(distance);
+ else
+ flags |= RENDER_DOPPLER | RENDER_DISTANCE;
+
+ if(m_pitch->getSpecs().channels != CHANNELS_MONO)
+ {
+ m_volume = m_user_volume;
+ m_pitch->setPitch(m_user_pitch);
+ return;
+ }
+
+ flags = ~(flags | m_flags | m_device->m_flags);
+
+ // Doppler and Pitch
+
+ if(flags & RENDER_DOPPLER)
+ {
+ float vls;
+ if(m_relative)
+ vls = 0;
+ else
+ vls = SL * m_device->m_velocity / distance;
+ float vss = SL * m_velocity / distance;
+ float max = m_device->m_speed_of_sound / m_device->m_doppler_factor;
+ if(vss >= max)
+ {
+ m_pitch->setPitch(PITCH_MAX);
+ }
+ else
+ {
+ if(vls > max)
+ vls = max;
+
+ m_pitch->setPitch((m_device->m_speed_of_sound - m_device->m_doppler_factor * vls) / (m_device->m_speed_of_sound - m_device->m_doppler_factor * vss) * m_user_pitch);
+ }
+ }
+ else
+ m_pitch->setPitch(m_user_pitch);
+
+ if(flags & RENDER_VOLUME)
+ {
+ // Distance
+
+ if(flags & RENDER_DISTANCE)
+ {
+ if(m_device->m_distance_model == DISTANCE_MODEL_INVERSE_CLAMPED ||
+ m_device->m_distance_model == DISTANCE_MODEL_LINEAR_CLAMPED ||
+ m_device->m_distance_model == DISTANCE_MODEL_EXPONENT_CLAMPED)
+ {
+ distance = std::max(std::min(m_distance_max, distance), m_distance_reference);
+ }
+
+ switch(m_device->m_distance_model)
+ {
+ case DISTANCE_MODEL_INVERSE:
+ case DISTANCE_MODEL_INVERSE_CLAMPED:
+ m_volume = m_distance_reference / (m_distance_reference + m_attenuation * (distance - m_distance_reference));
+ break;
+ case DISTANCE_MODEL_LINEAR:
+ case DISTANCE_MODEL_LINEAR_CLAMPED:
+ {
+ float temp = m_distance_max - m_distance_reference;
+ if(temp == 0)
+ {
+ if(distance > m_distance_reference)
+ m_volume = 0.0f;
+ else
+ m_volume = 1.0f;
+ }
+ else
+ m_volume = 1.0f - m_attenuation * (distance - m_distance_reference) / (m_distance_max - m_distance_reference);
+ break;
+ }
+ case DISTANCE_MODEL_EXPONENT:
+ case DISTANCE_MODEL_EXPONENT_CLAMPED:
+ if(m_distance_reference == 0)
+ m_volume = 0;
+ else
+ m_volume = std::pow(distance / m_distance_reference, -m_attenuation);
+ break;
+ default:
+ m_volume = 1.0f;
+ }
+ }
+ else
+ m_volume = 1.0f;
+
+ // Cone
+
+ if(flags & RENDER_CONE)
+ {
+ Vector3 SZ = m_orientation.getLookAt();
+
+ float phi = std::acos(float(SZ * SL / (SZ.length() * SL.length())));
+ float t = (phi - m_cone_angle_inner)/(m_cone_angle_outer - m_cone_angle_inner);
+
+ if(t > 0)
+ {
+ if(t > 1)
+ m_volume *= m_cone_volume_outer;
+ else
+ m_volume *= 1 + t * (m_cone_volume_outer - 1);
+ }
+ }
+
+ if(m_volume > m_volume_max)
+ m_volume = m_volume_max;
+ else if(m_volume < m_volume_min)
+ m_volume = m_volume_min;
+
+ // Volume
+
+ m_volume *= m_user_volume;
+ }
+
+ // 3D Cue
+
+ Quaternion orientation;
+
+ if(!m_relative)
+ orientation = m_device->m_orientation;
+
+ Vector3 Z = orientation.getLookAt();
+ Vector3 N = orientation.getUp();
+ Vector3 A = N * ((SL * N) / (N * N)) - SL;
+
+ float Asquare = A * A;
+
+ if(Asquare > 0)
+ {
+ float phi = std::acos(float(Z * A / (Z.length() * std::sqrt(Asquare))));
+ if(N.cross(Z) * A > 0)
+ phi = -phi;
+
+ m_mapper->setMonoAngle(phi);
+ }
+ else
+ m_mapper->setMonoAngle(m_relative ? m_user_pan * M_PI / 2.0 : 0);
+}
+
+void SoftwareDevice::SoftwareHandle::setSpecs(Specs specs)
+{
+ m_mapper->setChannels(specs.channels);
+ m_resampler->setRate(specs.rate);
+}
+
+bool SoftwareDevice::SoftwareHandle::pause()
+{
+ return pause(false);
+}
+
+bool SoftwareDevice::SoftwareHandle::resume()
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PAUSED)
+ {
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+
+ m_device->m_playingSounds.push_back(This);
+
+ if(!m_device->m_playback)
+ m_device->playing(m_device->m_playback = true);
+ m_status = STATUS_PLAYING;
+
+ return true;
+ }
+ }
+ }
+
+ }
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_status = STATUS_INVALID;
+
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+
+ return true;
+ }
+ }
+
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_keep = keep;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_pitch->setPitch(m_user_pitch);
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+
+ if(m_status == STATUS_STOPPED)
+ m_status = STATUS_PAUSED;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getPosition()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return 0.0f;
+
+ float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
+
+ return position;
+}
+
+Status SoftwareDevice::SoftwareHandle::getStatus()
+{
+ return m_status;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolume()
+{
+ return m_user_volume;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+ m_user_volume = volume;
+
+ if(volume == 0)
+ {
+ m_old_volume = m_volume = volume;
+ m_flags |= RENDER_VOLUME;
+ }
+ else
+ m_flags &= ~RENDER_VOLUME;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getPitch()
+{
+ return m_user_pitch;
+}
+
+bool SoftwareDevice::SoftwareHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+ if(pitch > 0.0f)
+ m_user_pitch = pitch;
+ return true;
+}
+
+int SoftwareDevice::SoftwareHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool SoftwareDevice::SoftwareHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+
+ if(m_status == STATUS_STOPPED && (count > m_loopcount || count < 0))
+ m_status = STATUS_PAUSED;
+
+ m_loopcount = count;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ return true;
+}
+
+
+
+/******************************************************************************/
+/******************** SoftwareHandle 3DHandle Code ************************/
+/******************************************************************************/
+
+Vector3 SoftwareDevice::SoftwareHandle::getLocation()
+{
+ if(!m_status)
+ return Vector3();
+
+ return m_location;
+}
+
+bool SoftwareDevice::SoftwareHandle::setLocation(const Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ m_location = location;
+
+ return true;
+}
+
+Vector3 SoftwareDevice::SoftwareHandle::getVelocity()
+{
+ if(!m_status)
+ return Vector3();
+
+ return m_velocity;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVelocity(const Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ m_velocity = velocity;
+
+ return true;
+}
+
+Quaternion SoftwareDevice::SoftwareHandle::getOrientation()
+{
+ if(!m_status)
+ return Quaternion();
+
+ return m_orientation;
+}
+
+bool SoftwareDevice::SoftwareHandle::setOrientation(const Quaternion& orientation)
+{
+ if(!m_status)
+ return false;
+
+ m_orientation = orientation;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::isRelative()
+{
+ if(!m_status)
+ return false;
+
+ return m_relative;
+}
+
+bool SoftwareDevice::SoftwareHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ m_relative = relative;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolumeMaximum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_volume_max;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_volume_max = volume;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolumeMinimum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_volume_min;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_volume_min = volume;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getDistanceMaximum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_max;
+}
+
+bool SoftwareDevice::SoftwareHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_max = distance;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getDistanceReference()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_reference;
+}
+
+bool SoftwareDevice::SoftwareHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_reference = distance;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getAttenuation()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_attenuation;
+}
+
+bool SoftwareDevice::SoftwareHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ m_attenuation = factor;
+
+ if(factor == 0)
+ m_flags |= RENDER_DISTANCE;
+ else
+ m_flags &= ~RENDER_DISTANCE;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeAngleOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_outer * 360.0f / M_PI;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_angle_outer = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeAngleInner()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_inner * 360.0f / M_PI;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ if(angle >= 360)
+ m_flags |= RENDER_CONE;
+ else
+ m_flags &= ~RENDER_CONE;
+
+ m_cone_angle_inner = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeVolumeOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_volume_outer;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_volume_outer = volume;
+
+ return true;
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+void SoftwareDevice::create()
+{
+ m_playback = false;
+ m_volume = 1.0f;
+ m_mixer = std::shared_ptr<Mixer>(new Mixer(m_specs));
+ m_speed_of_sound = 343.3f;
+ m_doppler_factor = 1.0f;
+ m_distance_model = DISTANCE_MODEL_INVERSE_CLAMPED;
+ m_flags = 0;
+ m_quality = false;
+}
+
+void SoftwareDevice::destroy()
+{
+ if(m_playback)
+ playing(m_playback = false);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+}
+
+void SoftwareDevice::mix(data_t* buffer, int length)
+{
+ m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ {
+ std::shared_ptr<SoftwareDevice::SoftwareHandle> sound;
+ int len;
+ int pos;
+ bool eos;
+ std::list<std::shared_ptr<SoftwareDevice::SoftwareHandle> > stopSounds;
+ std::list<std::shared_ptr<SoftwareDevice::SoftwareHandle> > pauseSounds;
+ sample_t* buf = m_buffer.getBuffer();
+
+ m_mixer->clear(length);
+
+ // for all sounds
+ for(auto& sound : m_playingSounds)
+ {
+ // get the buffer from the source
+ pos = 0;
+ len = length;
+
+ // update 3D Info
+ sound->update();
+
+ try
+ {
+ sound->m_reader->read(len, eos, buf);
+
+ // in case of looping
+ while(pos + len < length && sound->m_loopcount && eos)
+ {
+ m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
+
+ pos += len;
+
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
+
+ sound->m_reader->seek(0);
+
+ len = length - pos;
+ sound->m_reader->read(len, eos, buf);
+
+ // prevent endless loop
+ if(!len)
+ break;
+ }
+ }
+ catch(Exception& e)
+ {
+ len = 0;
+ std::cerr << "Caught exception while reading sound data during playback with software mixing: " << e.getMessage() << std::endl;
+ }
+
+ m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
+
+ // in case the end of the sound is reached
+ if(eos && !sound->m_loopcount)
+ {
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
+
+ if(sound->m_keep)
+ pauseSounds.push_back(sound);
+ else
+ stopSounds.push_back(sound);
+ }
+ }
+
+ // superpose
+ m_mixer->read(buffer, m_volume);
+
+ // cleanup
+ for(auto& sound : pauseSounds)
+ sound->pause(true);
+
+ for(auto& sound : stopSounds)
+ sound->stop();
+
+ pauseSounds.clear();
+ stopSounds.clear();
+ }
+}
+
+void SoftwareDevice::setPanning(IHandle* handle, float pan)
+{
+ SoftwareDevice::SoftwareHandle* h = dynamic_cast<SoftwareDevice::SoftwareHandle*>(handle);
+ h->m_user_pan = pan;
+}
+
+void SoftwareDevice::setQuality(bool quality)
+{
+ m_quality = quality;
+}
+
+void SoftwareDevice::setSpecs(Specs specs)
+{
+ m_specs.specs = specs;
+ m_mixer->setSpecs(specs);
+
+ for(auto& sound : m_playingSounds)
+ {
+ sound->setSpecs(specs);
+ }
+}
+
+SoftwareDevice::SoftwareDevice()
+{
+}
+
+DeviceSpecs SoftwareDevice::getSpecs() const
+{
+ return m_specs;
+}
+
+std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ // prepare the reader
+ // pitch
+
+ std::shared_ptr<PitchReader> pitch = std::shared_ptr<PitchReader>(new PitchReader(reader, 1));
+ reader = std::shared_ptr<IReader>(pitch);
+
+ std::shared_ptr<ResampleReader> resampler;
+
+ // resample
+ if(m_quality)
+ resampler = std::shared_ptr<ResampleReader>(new JOSResampleReader(reader, m_specs.rate));
+ else
+ resampler = std::shared_ptr<ResampleReader>(new LinearResampleReader(reader, m_specs.rate));
+ reader = std::shared_ptr<IReader>(resampler);
+
+ // rechannel
+ std::shared_ptr<ChannelMapperReader> mapper = std::shared_ptr<ChannelMapperReader>(new ChannelMapperReader(reader, m_specs.channels));
+ reader = std::shared_ptr<IReader>(mapper);
+
+ if(!reader.get())
+ return std::shared_ptr<IHandle>();
+
+ // play sound
+ std::shared_ptr<SoftwareDevice::SoftwareHandle> sound = std::shared_ptr<SoftwareDevice::SoftwareHandle>(new SoftwareDevice::SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_playingSounds.push_back(sound);
+
+ if(!m_playback)
+ playing(m_playback = true);
+
+ return std::shared_ptr<IHandle>(sound);
+}
+
+std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return play(sound->createReader(), keep);
+}
+
+void SoftwareDevice::stopAll()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+}
+
+void SoftwareDevice::lock()
+{
+ m_mutex.lock();
+}
+
+void SoftwareDevice::unlock()
+{
+ m_mutex.unlock();
+}
+
+float SoftwareDevice::getVolume() const
+{
+ return m_volume;
+}
+
+void SoftwareDevice::setVolume(float volume)
+{
+ m_volume = volume;
+}
+
+ISynchronizer* SoftwareDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+Vector3 SoftwareDevice::getListenerLocation() const
+{
+ return m_location;
+}
+
+void SoftwareDevice::setListenerLocation(const Vector3& location)
+{
+ m_location = location;
+}
+
+Vector3 SoftwareDevice::getListenerVelocity() const
+{
+ return m_velocity;
+}
+
+void SoftwareDevice::setListenerVelocity(const Vector3& velocity)
+{
+ m_velocity = velocity;
+}
+
+Quaternion SoftwareDevice::getListenerOrientation() const
+{
+ return m_orientation;
+}
+
+void SoftwareDevice::setListenerOrientation(const Quaternion& orientation)
+{
+ m_orientation = orientation;
+}
+
+float SoftwareDevice::getSpeedOfSound() const
+{
+ return m_speed_of_sound;
+}
+
+void SoftwareDevice::setSpeedOfSound(float speed)
+{
+ m_speed_of_sound = speed;
+}
+
+float SoftwareDevice::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void SoftwareDevice::setDopplerFactor(float factor)
+{
+ m_doppler_factor = factor;
+ if(factor == 0)
+ m_flags |= RENDER_DOPPLER;
+ else
+ m_flags &= ~RENDER_DOPPLER;
+}
+
+DistanceModel SoftwareDevice::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void SoftwareDevice::setDistanceModel(DistanceModel model)
+{
+ m_distance_model = model;
+ if(model == DISTANCE_MODEL_INVALID)
+ m_flags |= RENDER_DISTANCE;
+ else
+ m_flags &= ~RENDER_DISTANCE;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/File.cpp b/extern/audaspace/src/file/File.cpp
new file mode 100644
index 00000000000..0cdecb03657
--- /dev/null
+++ b/extern/audaspace/src/file/File.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "file/File.h"
+#include "file/FileManager.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+File::File(std::string filename) :
+ m_filename(filename)
+{
+}
+
+File::File(const data_t* buffer, int size) :
+ m_buffer(new Buffer(size))
+{
+ std::memcpy(m_buffer->getBuffer(), buffer, size);
+}
+
+std::shared_ptr<IReader> File::createReader()
+{
+ if(m_buffer.get())
+ return FileManager::createReader(m_buffer);
+ else
+ return FileManager::createReader(m_filename);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/FileManager.cpp b/extern/audaspace/src/file/FileManager.cpp
new file mode 100644
index 00000000000..f8ef8deb409
--- /dev/null
+++ b/extern/audaspace/src/file/FileManager.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "file/FileManager.h"
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+#include "Exception.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::list<std::shared_ptr<IFileInput>>& FileManager::inputs()
+{
+ static std::list<std::shared_ptr<IFileInput>> inputs;
+ return inputs;
+}
+
+std::list<std::shared_ptr<IFileOutput>>& FileManager::outputs()
+{
+ static std::list<std::shared_ptr<IFileOutput>> outputs;
+ return outputs;
+}
+
+void FileManager::registerInput(std::shared_ptr<IFileInput> input)
+{
+ inputs().push_back(input);
+}
+
+void FileManager::registerOutput(std::shared_ptr<aud::IFileOutput> output)
+{
+ outputs().push_back(output);
+}
+
+std::shared_ptr<IReader> FileManager::createReader(std::string filename)
+{
+ for(std::shared_ptr<IFileInput> input : inputs())
+ {
+ try
+ {
+ return input->createReader(filename);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
+}
+
+std::shared_ptr<IReader> FileManager::createReader(std::shared_ptr<Buffer> buffer)
+{
+ for(std::shared_ptr<IFileInput> input : inputs())
+ {
+ try
+ {
+ return input->createReader(buffer);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
+}
+
+std::shared_ptr<IWriter> FileManager::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ for(std::shared_ptr<IFileOutput> output : outputs())
+ {
+ try
+ {
+ return output->createWriter(filename, specs, format, codec, bitrate);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be written with any installed writer.");
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/FileWriter.cpp b/extern/audaspace/src/file/FileWriter.cpp
new file mode 100644
index 00000000000..a6bb0f0049a
--- /dev/null
+++ b/extern/audaspace/src/file/FileWriter.cpp
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "file/FileWriter.h"
+#include "file/FileManager.h"
+#include "util/Buffer.h"
+#include "IReader.h"
+#include "Exception.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<IWriter> FileWriter::createWriter(std::string filename,DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return FileManager::createWriter(filename, specs, format, codec, bitrate);
+}
+
+void FileWriter::writeReader(std::shared_ptr<IReader> reader, std::shared_ptr<IWriter> writer, unsigned int length, unsigned int buffersize)
+{
+ Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
+ sample_t* buf = buffer.getBuffer();
+
+ int len;
+ bool eos = false;
+ int channels = writer->getSpecs().channels;
+
+ for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+ {
+ len = buffersize;
+ if((len > length - pos) && (length > 0))
+ len = length - pos;
+ reader->read(len, eos, buf);
+
+ for(int i = 0; i < len * channels; i++)
+ {
+ // clamping!
+ if(buf[i] > 1)
+ buf[i] = 1;
+ else if(buf[i] < -1)
+ buf[i] = -1;
+ }
+
+ writer->write(len, buf);
+ }
+}
+
+void FileWriter::writeReader(std::shared_ptr<IReader> reader, std::vector<std::shared_ptr<IWriter> >& writers, unsigned int length, unsigned int buffersize)
+{
+ Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
+ Buffer buffer2(buffersize * sizeof(sample_t));
+ sample_t* buf = buffer.getBuffer();
+ sample_t* buf2 = buffer2.getBuffer();
+
+ int len;
+ bool eos = false;
+ int channels = reader->getSpecs().channels;
+
+ for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+ {
+ len = buffersize;
+ if((len > length - pos) && (length > 0))
+ len = length - pos;
+ reader->read(len, eos, buf);
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < len; i++)
+ {
+ // clamping!
+ if(buf[i * channels + channel] > 1)
+ buf2[i] = 1;
+ else if(buf[i * channels + channel] < -1)
+ buf2[i] = -1;
+ else
+ buf2[i] = buf[i * channels + channel];
+ }
+
+ writers[channel]->write(len, buf2);
+ }
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ADSR.cpp b/extern/audaspace/src/fx/ADSR.cpp
new file mode 100644
index 00000000000..f147affda72
--- /dev/null
+++ b/extern/audaspace/src/fx/ADSR.cpp
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/ADSR.h"
+#include "fx/ADSRReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ADSR::ADSR(std::shared_ptr<ISound> sound, float attack, float decay, float sustain, float release) :
+ Effect(sound),
+ m_attack(attack), m_decay(decay), m_sustain(sustain), m_release(release)
+{
+}
+
+float ADSR::getAttack() const
+{
+ return m_attack;
+}
+
+void ADSR::setAttack(float attack)
+{
+ m_attack = attack;
+}
+
+float ADSR::getDecay() const
+{
+ return m_decay;
+}
+
+void ADSR::setDecay(float decay)
+{
+ m_decay = decay;
+}
+
+float ADSR::getSustain() const
+{
+ return m_sustain;
+}
+
+void ADSR::setSustain(float sustain)
+{
+ m_sustain = sustain;
+}
+
+float ADSR::getRelease() const
+{
+ return m_release;
+}
+
+void ADSR::setRelease(float release)
+{
+ m_release = release;
+}
+
+std::shared_ptr<IReader> ADSR::createReader()
+{
+ return std::shared_ptr<IReader>(new ADSRReader(getReader(), m_attack, m_decay, m_sustain, m_release));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ADSRReader.cpp b/extern/audaspace/src/fx/ADSRReader.cpp
new file mode 100644
index 00000000000..6499b55468e
--- /dev/null
+++ b/extern/audaspace/src/fx/ADSRReader.cpp
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/ADSRReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ADSRReader::ADSRReader(std::shared_ptr<IReader> reader, float attack, float decay, float sustain, float release) :
+ EffectReader(reader),
+ m_attack(attack), m_decay(decay), m_sustain(sustain), m_release(release)
+{
+ nextState(ADSR_STATE_ATTACK);
+}
+
+ADSRReader::~ADSRReader()
+{
+}
+
+void ADSRReader::nextState(ADSRState state)
+{
+ m_state = state;
+
+ switch(m_state)
+ {
+ case ADSR_STATE_ATTACK:
+ m_level = 0;
+ if(m_attack <= 0)
+ {
+ nextState(ADSR_STATE_DECAY);
+ return;
+ }
+ return;
+ case ADSR_STATE_DECAY:
+ if(m_decay <= 0)
+ {
+ nextState(ADSR_STATE_SUSTAIN);
+ return;
+ }
+ if(m_level > 1.0)
+ m_level = 1 - (m_level - 1) * m_attack / m_decay * (1 - m_sustain);
+ if(m_level <= m_sustain)
+ nextState(ADSR_STATE_SUSTAIN);
+ break;
+ case ADSR_STATE_SUSTAIN:
+ m_level = m_sustain;
+ break;
+ case ADSR_STATE_RELEASE:
+ if(m_release <= 0)
+ {
+ nextState(ADSR_STATE_INVALID);
+ return;
+ }
+ break;
+ case ADSR_STATE_INVALID:
+ break;
+ }
+}
+
+void ADSRReader::read(int & length, bool &eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ m_reader->read(length, eos, buffer);
+
+ for(int i = 0; i < length; i++)
+ {
+ for(int channel = 0; channel < specs.channels; channel++)
+ {
+ buffer[i * specs.channels + channel] *= m_level;
+ }
+
+ switch(m_state)
+ {
+ case ADSR_STATE_ATTACK:
+ m_level += 1 / m_attack / specs.rate;
+ if(m_level >= 1)
+ nextState(ADSR_STATE_DECAY);
+ break;
+ case ADSR_STATE_DECAY:
+ m_level -= (1 - m_sustain) / m_decay / specs.rate;
+ if(m_level <= m_sustain)
+ nextState(ADSR_STATE_SUSTAIN);
+ break;
+ case ADSR_STATE_SUSTAIN:
+ break;
+ case ADSR_STATE_RELEASE:
+ m_level -= m_sustain / m_release / specs.rate ;
+ if(m_level <= 0)
+ nextState(ADSR_STATE_INVALID);
+ break;
+ case ADSR_STATE_INVALID:
+ length = i;
+ return;
+ }
+ }
+}
+
+void ADSRReader::release()
+{
+ nextState(ADSR_STATE_RELEASE);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Accumulator.cpp b/extern/audaspace/src/fx/Accumulator.cpp
new file mode 100644
index 00000000000..ba8e6a2841e
--- /dev/null
+++ b/extern/audaspace/src/fx/Accumulator.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Accumulator.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+sample_t Accumulator::accumulatorFilterAdditive(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 Accumulator::accumulatorFilter(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;
+}
+
+Accumulator::Accumulator(std::shared_ptr<ISound> sound,
+ bool additive) :
+ Effect(sound),
+ m_additive(additive)
+{
+}
+
+std::shared_ptr<IReader> Accumulator::createReader()
+{
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(getReader(), 2, 2, m_additive ? accumulatorFilterAdditive : accumulatorFilter));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BaseIIRFilterReader.cpp b/extern/audaspace/src/fx/BaseIIRFilterReader.cpp
new file mode 100644
index 00000000000..6505e5ea600
--- /dev/null
+++ b/extern/audaspace/src/fx/BaseIIRFilterReader.cpp
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/BaseIIRFilterReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BaseIIRFilterReader::BaseIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out) :
+ EffectReader(reader),
+ m_specs(reader->getSpecs()),
+ m_xlen(in), m_ylen(out),
+ m_xpos(0), m_ypos(0), m_channel(0)
+{
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
+
+ std::memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ std::memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
+}
+
+BaseIIRFilterReader::~BaseIIRFilterReader()
+{
+ delete[] m_x;
+ delete[] m_y;
+}
+
+void BaseIIRFilterReader::setLengths(int in, int out)
+{
+ if(in != m_xlen)
+ {
+ sample_t* xn = new sample_t[in * m_specs.channels];
+ std::memset(xn, 0, sizeof(sample_t) * in * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= in && i <= m_xlen; i++)
+ {
+ xn[(in - i) * m_specs.channels + m_channel] = x(-i);
+ }
+ }
+
+ delete[] m_x;
+ m_x = xn;
+ m_xpos = 0;
+ m_xlen = in;
+ }
+
+ if(out != m_ylen)
+ {
+ sample_t* yn = new sample_t[out * m_specs.channels];
+ std::memset(yn, 0, sizeof(sample_t) * out * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= out && i <= m_ylen; i++)
+ {
+ yn[(out - i) * m_specs.channels + m_channel] = y(-i);
+ }
+ }
+
+ delete[] m_y;
+ m_y = yn;
+ m_ypos = 0;
+ m_ylen = out;
+ }
+}
+
+void BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ if(specs.channels != m_specs.channels)
+ {
+ m_specs.channels = specs.channels;
+
+ delete[] m_x;
+ delete[] m_y;
+
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
+
+ std::memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ std::memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
+ }
+
+ if(specs.rate != m_specs.rate)
+ {
+ m_specs = specs;
+ sampleRateChanged(m_specs.rate);
+ }
+
+ m_reader->read(length, eos, buffer);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ m_x[m_xpos * m_specs.channels + m_channel] = buffer[i * m_specs.channels + m_channel];
+ m_y[m_ypos * m_specs.channels + m_channel] = buffer[i * m_specs.channels + m_channel] = filter();
+
+ m_xpos = m_xlen ? (m_xpos + 1) % m_xlen : 0;
+ m_ypos = m_ylen ? (m_ypos + 1) % m_ylen : 0;
+ }
+ }
+}
+
+void BaseIIRFilterReader::sampleRateChanged(SampleRate rate)
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BinauralReader.cpp b/extern/audaspace/src/fx/BinauralReader.cpp
new file mode 100644
index 00000000000..2792adada8a
--- /dev/null
+++ b/extern/audaspace/src/fx/BinauralReader.cpp
@@ -0,0 +1,255 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/BinauralReader.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <algorithm>
+
+#define NUM_OUTCHANNELS 2
+#define NUM_CONVOLVERS 4
+#define CROSSFADE_SAMPLES 1024
+
+AUD_NAMESPACE_BEGIN
+BinauralReader::BinauralReader(std::shared_ptr<IReader> reader, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_threadPool(threadPool), m_position(0), m_eosReader(false), m_eosTail(false), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS)
+{
+ if(m_hrtfs->isEmpty())
+ AUD_THROW(StateException, "The provided HRTF object is empty");
+ if(m_reader->getSpecs().channels != 1)
+ AUD_THROW(StateException, "The sound must have only one channel");
+ if(m_reader->getSpecs().rate != m_hrtfs->getSpecs().rate)
+ AUD_THROW(StateException, "The sound and the HRTFs must have the same rate");
+ m_M = m_L = m_N / 2;
+
+ m_RealAzimuth = m_Azimuth = m_source->getAzimuth();
+ m_RealElevation = m_Elevation = m_source->getElevation();
+ auto irs = m_hrtfs->getImpulseResponse(m_RealAzimuth, m_RealElevation);
+ for(unsigned int i = 0; i < NUM_CONVOLVERS; i++)
+ if(i%NUM_OUTCHANNELS==0)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(irs.first->getChannel(0), irs.first->getLength(), m_threadPool, plan)));
+ else
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(irs.second->getChannel(0), irs.second->getLength(), m_threadPool, plan)));
+ m_futures.resize(NUM_CONVOLVERS);
+
+ m_outBuffer = (sample_t*)std::malloc(m_L*NUM_OUTCHANNELS*sizeof(sample_t));
+ m_eOutBufLen = m_outBufLen = m_outBufferPos = m_L * NUM_OUTCHANNELS;
+ m_inBuffer = (sample_t*)std::malloc(m_L * sizeof(sample_t));
+ for(int i = 0; i < NUM_CONVOLVERS; i++)
+ m_vecOut.push_back((sample_t*)std::calloc(m_L, sizeof(sample_t)));
+}
+
+BinauralReader::~BinauralReader()
+{
+ std::free(m_outBuffer);
+ std::free(m_inBuffer);
+ for(int i = 0; i < m_vecOut.size(); i++)
+ std::free(m_vecOut[i]);
+}
+
+bool BinauralReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void BinauralReader::seek(int position)
+{
+ m_position = position;
+ m_reader->seek(position);
+ for(int i = 0; i < NUM_CONVOLVERS; i++)
+ m_convolvers[i]->reset();
+ m_eosTail = false;
+ m_eosReader = false;
+ m_outBufferPos = m_eOutBufLen = m_outBufLen;
+ m_transition = false;
+ m_transPos = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+}
+
+int BinauralReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int BinauralReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs BinauralReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.channels = CHANNELS_STEREO;
+ return specs;
+}
+
+void BinauralReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int samples = 0;
+ int iteration = 0;
+ if(length <= 0)
+ {
+ length = 0;
+ eos = (m_eosTail && m_outBufferPos >= m_eOutBufLen);
+ return;
+ }
+
+ eos = false;
+ int writePos = 0;
+ do
+ {
+ int bufRest = m_eOutBufLen - m_outBufferPos;
+ int writeLength = std::min((length*NUM_OUTCHANNELS) - writePos, m_eOutBufLen + bufRest);
+ if(bufRest < writeLength || (m_eOutBufLen == 0 && m_eosTail))
+ {
+ if(bufRest > 0)
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
+ if(!m_eosTail)
+ {
+ int n = NUM_OUTCHANNELS;
+ if(m_transition)
+ n = NUM_CONVOLVERS;
+ else if(checkSource())
+ n = NUM_CONVOLVERS;
+ loadBuffer(n);
+
+ int len = std::min(std::abs(writeLength - bufRest), m_eOutBufLen);
+ std::memcpy(buffer + writePos + bufRest, m_outBuffer, len*sizeof(sample_t));
+ samples += len;
+ m_outBufferPos = len;
+ writeLength = std::min((length*NUM_OUTCHANNELS) - writePos, m_eOutBufLen + bufRest);
+ }
+ else
+ {
+ m_outBufferPos += bufRest;
+ length = (writePos+bufRest) / NUM_OUTCHANNELS;
+ eos = true;
+ return;
+ }
+ }
+ else
+ {
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
+ m_outBufferPos += writeLength;
+ }
+ writePos += writeLength;
+ iteration++;
+ } while(writePos < length*NUM_OUTCHANNELS);
+ m_position += length;
+}
+
+bool BinauralReader::checkSource()
+{
+ if((m_Azimuth != m_source->getAzimuth() || m_Elevation != m_source->getElevation()) && (!m_eosReader && !m_eosTail))
+ {
+ float az = m_Azimuth = m_source->getAzimuth();
+ float el = m_Elevation = m_source->getElevation();
+ auto irs = m_hrtfs->getImpulseResponse(az, el);
+ if(az != m_RealAzimuth || el != m_RealElevation)
+ {
+ m_RealAzimuth = az;
+ m_RealElevation = el;
+ for(int i = 0; i < NUM_OUTCHANNELS; i++)
+ {
+ auto temp = std::move(m_convolvers[i]);
+ m_convolvers[i] = std::move(m_convolvers[i + NUM_OUTCHANNELS]);
+ m_convolvers[i + NUM_OUTCHANNELS] = std::move(temp);
+ }
+ for(int i = 0; i < NUM_OUTCHANNELS; i++)
+ if(i%NUM_OUTCHANNELS == 0)
+ m_convolvers[i]->setImpulseResponse(irs.first->getChannel(0));
+ else
+ m_convolvers[i]->setImpulseResponse(irs.second->getChannel(0));
+
+ m_transPos = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+ m_transition = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+void BinauralReader::loadBuffer(int nConvolvers)
+{
+ m_lastLengthIn = m_L;
+ m_reader->read(m_lastLengthIn, m_eosReader, m_inBuffer);
+ if(!m_eosReader || m_lastLengthIn > 0)
+ {
+ int len = m_lastLengthIn;
+ for(int i = 0; i < nConvolvers; i++)
+ m_futures[i] = m_threadPool->enqueue(&BinauralReader::threadFunction, this, i, true);
+ for(int i = 0; i < nConvolvers; i++)
+ len = m_futures[i].get();
+
+ joinByChannel(0, len, nConvolvers);
+ m_eOutBufLen = len*NUM_OUTCHANNELS;
+ }
+ else if(!m_eosTail)
+ {
+ int len = m_lastLengthIn = m_L;
+ for(int i = 0; i < nConvolvers; i++)
+ m_futures[i] = m_threadPool->enqueue(&BinauralReader::threadFunction, this, i, false);
+ for(int i = 0; i < nConvolvers; i++)
+ len = m_futures[i].get();
+
+ joinByChannel(0, len, nConvolvers);
+ m_eOutBufLen = len*NUM_OUTCHANNELS;
+ }
+}
+
+void BinauralReader::joinByChannel(int start, int len, int nConvolvers)
+{
+ int k = 0;
+ float vol = 0;
+ const int l = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+ for(int i = 0; i < len*NUM_OUTCHANNELS; i += NUM_OUTCHANNELS)
+ {
+ if(m_transition)
+ {
+ vol = (m_transPos - i) / (float)l;
+ if(vol > 1.0f)
+ vol = 1.0f;
+ else if(vol < 0.0f)
+ vol = 0.0f;
+ }
+
+ for(int j = 0; j < NUM_OUTCHANNELS; j++)
+ m_outBuffer[i + j + start] = ((m_vecOut[j][k] * (1.0f - vol)) + (m_vecOut[j + NUM_OUTCHANNELS][k] * vol))*m_source->getVolume();
+ k++;
+ }
+ if(m_transition)
+ {
+ m_transPos -= len*NUM_OUTCHANNELS;
+ if(m_transPos <= 0)
+ {
+ m_transition = false;
+ m_transPos = l;
+ }
+ }
+}
+
+int BinauralReader::threadFunction(int id, bool input)
+{
+ int l = m_lastLengthIn;
+ if(input)
+ m_convolvers[id]->getNext(m_inBuffer, m_vecOut[id], l, m_eosTail);
+ else
+ m_convolvers[id]->getNext(nullptr, m_vecOut[id], l, m_eosTail);
+ return l;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BinauralSound.cpp b/extern/audaspace/src/fx/BinauralSound.cpp
new file mode 100644
index 00000000000..7b9508c9944
--- /dev/null
+++ b/extern/audaspace/src/fx/BinauralSound.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/BinauralSound.h"
+#include "fx/BinauralReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BinauralSound::BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool) :
+ BinauralSound(sound, hrtfs, source, threadPool, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+BinauralSound::BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_sound(sound), m_hrtfs(hrtfs), m_source(source), m_threadPool(threadPool), m_plan(plan)
+{
+}
+
+std::shared_ptr<IReader> BinauralSound::createReader()
+{
+ return std::make_shared<BinauralReader>(m_sound->createReader(), m_hrtfs, m_source, m_threadPool, m_plan);
+}
+
+std::shared_ptr<HRTF> BinauralSound::getHRTFs()
+{
+ return m_hrtfs;
+}
+
+void BinauralSound::setHRTFs(std::shared_ptr<HRTF> hrtfs)
+{
+ m_hrtfs = hrtfs;
+}
+
+std::shared_ptr<Source> BinauralSound::getSource()
+{
+ return m_source;
+}
+
+void BinauralSound::setSource(std::shared_ptr<Source> source)
+{
+ m_source = source;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Butterworth.cpp b/extern/audaspace/src/fx/Butterworth.cpp
new file mode 100644
index 00000000000..1d86cd799b8
--- /dev/null
+++ b/extern/audaspace/src/fx/Butterworth.cpp
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Butterworth.h"
+#include "fx/ButterworthCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Butterworth::Butterworth(std::shared_ptr<ISound> sound, float frequency) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new ButterworthCalculator(frequency)))
+{
+}
+
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ButterworthCalculator.cpp b/extern/audaspace/src/fx/ButterworthCalculator.cpp
new file mode 100644
index 00000000000..f249fd45f15
--- /dev/null
+++ b/extern/audaspace/src/fx/ButterworthCalculator.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/ButterworthCalculator.h"
+
+#include <cmath>
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+
+AUD_NAMESPACE_BEGIN
+
+ButterworthCalculator::ButterworthCalculator(float frequency) :
+ m_frequency(frequency)
+{
+}
+
+void ButterworthCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float omega = 2 * std::tan(m_frequency * M_PI / rate);
+ float o2 = omega * omega;
+ float o4 = o2 * o2;
+ float x1 = o2 + 2.0f * (float)BWPB41 * omega + 4.0f;
+ float x2 = o2 + 2.0f * (float)BWPB42 * omega + 4.0f;
+ float y1 = o2 - 2.0f * (float)BWPB41 * omega + 4.0f;
+ float y2 = o2 - 2.0f * (float)BWPB42 * omega + 4.0f;
+ float o228 = 2.0f * o2 - 8.0f;
+ float norm = x1 * x2;
+ 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]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp b/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp
new file mode 100644
index 00000000000..f24b6b6c9ec
--- /dev/null
+++ b/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+CallbackIIRFilterReader::CallbackIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out, doFilterIIR doFilter, endFilterIIR endFilter, void* data) :
+ BaseIIRFilterReader(reader, in, out),
+ m_filter(doFilter), m_endFilter(endFilter), m_data(data)
+{
+}
+
+CallbackIIRFilterReader::~CallbackIIRFilterReader()
+{
+ if(m_endFilter)
+ m_endFilter(m_data);
+}
+
+sample_t CallbackIIRFilterReader::filter()
+{
+ return m_filter(this, m_data);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Convolver.cpp b/extern/audaspace/src/fx/Convolver.cpp
new file mode 100644
index 00000000000..24b205e9282
--- /dev/null
+++ b/extern/audaspace/src/fx/Convolver.cpp
@@ -0,0 +1,156 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/Convolver.h"
+
+#include <cmath>
+#include <cstdlib>
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+Convolver::Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_tailCounter(0), m_eos(false)
+
+{
+ m_resetFlag = false;
+ m_futures.resize(m_numThreads);
+ for(int i = 0; i < m_irBuffers->size(); i++)
+ {
+ m_fftConvolvers.push_back(std::unique_ptr<FFTConvolver>(new FFTConvolver((*m_irBuffers)[i], plan)));
+ m_delayLine.push_front((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
+ }
+
+ m_accBuffer = (fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex));
+ for(int i = 0; i < m_numThreads; i++)
+ m_threadAccBuffers.push_back((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
+}
+
+Convolver::~Convolver()
+{
+ m_resetFlag = true;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ std::free(m_accBuffer);
+ for(auto buf : m_threadAccBuffers)
+ std::free(buf);
+ while(!m_delayLine.empty())
+ {
+ std::free(m_delayLine.front());
+ m_delayLine.pop_front();
+ }
+}
+
+void Convolver::getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos)
+{
+ if(length > m_L)
+ {
+ length = 0;
+ eos = m_eos;
+ return;
+ }
+ if(m_eos)
+ {
+ eos = m_eos;
+ length = 0;
+ return;
+ }
+
+ eos = false;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ if(inBuffer != nullptr)
+ m_fftConvolvers[0]->getNextFDL(inBuffer, reinterpret_cast<std::complex<sample_t>*>(m_accBuffer), length, m_delayLine[0]);
+ else
+ {
+ m_tailCounter++;
+ std::memset(outBuffer, 0, m_L*sizeof(sample_t));
+ m_fftConvolvers[0]->getNextFDL(outBuffer, reinterpret_cast<std::complex<sample_t>*>(m_accBuffer), length, m_delayLine[0]);
+ }
+ m_delayLine.push_front(m_delayLine.back());
+ m_delayLine.pop_back();
+ length = m_L;
+ m_fftConvolvers[0]->IFFT_FDL(m_accBuffer, outBuffer, length);
+ std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+
+ if(m_tailCounter >= m_delayLine.size() && inBuffer == nullptr)
+ {
+ eos = m_eos = true;
+ length = m_irLength%m_M;
+ if(length == 0)
+ length = m_M;
+ }
+ else
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&Convolver::threadFunction, this, i);
+}
+
+void Convolver::reset()
+{
+ m_resetFlag = true;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ for(int i = 0; i < m_delayLine.size();i++)
+ std::memset(m_delayLine[i], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_fftConvolvers.size(); i++)
+ m_fftConvolvers[i]->clear();
+ std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+ m_tailCounter = 0;
+ m_eos = false;
+ m_resetFlag = false;
+}
+
+std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> Convolver::getImpulseResponse()
+{
+ return m_irBuffers;
+}
+
+void Convolver::setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir)
+{
+ reset();
+ m_irBuffers = ir;
+ for(int i = 0; i < m_irBuffers->size(); i++)
+ m_fftConvolvers[i]->setImpulseResponse((*m_irBuffers)[i]);
+}
+
+bool Convolver::threadFunction(int id)
+{
+ int total = m_irBuffers->size();
+ int share = std::ceil(((float)total - 1) / (float)m_numThreads);
+ int start = id*share + 1;
+ int end = std::min(start + share, total);
+
+ std::memset(m_threadAccBuffers[id], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+
+ for(int i = start; i < end && !m_resetFlag; i++)
+ m_fftConvolvers[i]->getNextFDL(reinterpret_cast<std::complex<sample_t>*>(m_delayLine[i]), reinterpret_cast<std::complex<sample_t>*>(m_threadAccBuffers[id]));
+
+ m_sumMutex.lock();
+ for(int i = 0; (i < m_N / 2 + 1) && !m_resetFlag; i++)
+ {
+ m_accBuffer[i][0] += m_threadAccBuffers[id][i][0];
+ m_accBuffer[i][1] += m_threadAccBuffers[id][i][1];
+ }
+ m_sumMutex.unlock();
+ return true;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ConvolverReader.cpp b/extern/audaspace/src/fx/ConvolverReader.cpp
new file mode 100644
index 00000000000..d5d9050f9a1
--- /dev/null
+++ b/extern/audaspace/src/fx/ConvolverReader.cpp
@@ -0,0 +1,203 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/ConvolverReader.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+
+AUD_NAMESPACE_BEGIN
+ConvolverReader::ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool), m_position(0)
+{
+ m_nChannelThreads = std::min((int)threadPool->getNumOfThreads(), m_inChannels);
+ m_futures.resize(m_nChannelThreads);
+
+ int irLength = m_ir->getLength();
+ if(m_irChannels != 1 && m_irChannels != m_inChannels)
+ AUD_THROW(StateException, "The impulse response and the sound must either have the same amount of channels or the impulse response must be mono");
+ if(m_reader->getSpecs().rate != m_ir->getSpecs().rate)
+ AUD_THROW(StateException, "The sound and the impulse response. must have the same rate");
+
+ m_M = m_L = m_N / 2;
+
+ if(m_irChannels > 1)
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(ir->getChannel(i), irLength, m_threadPool, plan)));
+ else
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(ir->getChannel(0), irLength, m_threadPool, plan)));
+
+ for(int i = 0; i < m_inChannels; i++)
+ m_vecInOut.push_back((sample_t*)std::malloc(m_L*sizeof(sample_t)));
+ m_outBuffer = (sample_t*)std::malloc(m_L*m_inChannels*sizeof(sample_t));
+ m_outBufLen = m_eOutBufLen = m_outBufferPos = m_L*m_inChannels;
+}
+
+ConvolverReader::~ConvolverReader()
+{
+ std::free(m_outBuffer);
+ for(int i = 0; i < m_inChannels; i++)
+ std::free(m_vecInOut[i]);
+}
+
+bool ConvolverReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void ConvolverReader::seek(int position)
+{
+ m_position = position;
+ m_reader->seek(position);
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers[i]->reset();
+ m_eosTail = false;
+ m_eosReader = false;
+ m_outBufferPos = m_eOutBufLen = m_outBufLen;
+}
+
+int ConvolverReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int ConvolverReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs ConvolverReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void ConvolverReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(length <= 0)
+ {
+ length = 0;
+ eos = (m_eosTail && m_outBufferPos >= m_eOutBufLen);
+ return;
+ }
+ eos = false;
+ int writePos = 0;
+ do
+ {
+ int bufRest = m_eOutBufLen - m_outBufferPos;
+ int writeLength = std::min((length*m_inChannels) - writePos, m_eOutBufLen + bufRest);
+ if(bufRest < writeLength || (m_eOutBufLen == 0 && m_eosTail))
+ {
+ if(bufRest > 0)
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
+ if(!m_eosTail)
+ {
+ loadBuffer();
+ int len = std::min(std::abs(writeLength - bufRest), m_eOutBufLen);
+ std::memcpy(buffer + writePos + bufRest, m_outBuffer, len*sizeof(sample_t));
+ m_outBufferPos = len;
+ writeLength = std::min((length*m_inChannels) - writePos, m_eOutBufLen + bufRest);
+ }
+ else
+ {
+ m_outBufferPos += bufRest;
+ length = (writePos + bufRest) / m_inChannels;
+ eos = true;
+ return;
+ }
+ }
+ else
+ {
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
+ m_outBufferPos += writeLength;
+ }
+ writePos += writeLength;
+ } while(writePos < length*m_inChannels);
+ m_position += length;
+}
+
+void ConvolverReader::loadBuffer()
+{
+ m_lastLengthIn = m_L;
+ m_reader->read(m_lastLengthIn, m_eosReader, m_outBuffer);
+ if(!m_eosReader || m_lastLengthIn>0)
+ {
+ divideByChannel(m_outBuffer, m_lastLengthIn*m_inChannels);
+ int len = m_lastLengthIn;
+
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&ConvolverReader::threadFunction, this, i, true);
+ for(auto &fut : m_futures)
+ len = fut.get();
+
+ joinByChannel(0, len);
+ m_eOutBufLen = len*m_inChannels;
+ }
+ else if(!m_eosTail)
+ {
+ int len = m_lastLengthIn = m_L;
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&ConvolverReader::threadFunction, this, i, false);
+ for(auto &fut : m_futures)
+ len = fut.get();
+
+ joinByChannel(0, len);
+ m_eOutBufLen = len*m_inChannels;
+ }
+}
+
+void ConvolverReader::divideByChannel(const sample_t* buffer, int len)
+{
+ int k = 0;
+ for(int i = 0; i < len; i += m_inChannels)
+ {
+ for(int j = 0; j < m_inChannels; j++)
+ m_vecInOut[j][k] = buffer[i + j];
+ k++;
+ }
+}
+
+void ConvolverReader::joinByChannel(int start, int len)
+{
+ int k = 0;
+ for(int i = 0; i < len*m_inChannels; i += m_inChannels)
+ {
+ for(int j = 0; j < m_vecInOut.size(); j++)
+ m_outBuffer[i + j + start] = m_vecInOut[j][k];
+ k++;
+ }
+}
+
+int ConvolverReader::threadFunction(int id, bool input)
+{
+ int share = std::ceil((float)m_inChannels / (float)m_nChannelThreads);
+ int start = id*share;
+ int end = std::min(start + share, m_inChannels);
+
+ int l=m_lastLengthIn;
+ for(int i = start; i < end; i++)
+ if(input)
+ m_convolvers[i]->getNext(m_vecInOut[i], m_vecInOut[i], l, m_eosTail);
+ else
+ m_convolvers[i]->getNext(nullptr, m_vecInOut[i], l, m_eosTail);
+
+ return l;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ConvolverSound.cpp b/extern/audaspace/src/fx/ConvolverSound.cpp
new file mode 100644
index 00000000000..9bdf5a66652
--- /dev/null
+++ b/extern/audaspace/src/fx/ConvolverSound.cpp
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/ConvolverSound.h"
+#include "fx/ConvolverReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ConvolverSound::ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool) :
+ ConvolverSound(sound, impulseResponse, threadPool, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+ConvolverSound::ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_sound(sound), m_impulseResponse(impulseResponse), m_threadPool(threadPool), m_plan(plan)
+{
+}
+
+std::shared_ptr<IReader> ConvolverSound::createReader()
+{
+ return std::make_shared<ConvolverReader>(m_sound->createReader(), m_impulseResponse, m_threadPool, m_plan);
+}
+
+std::shared_ptr<ImpulseResponse> ConvolverSound::getImpulseResponse()
+{
+ return m_impulseResponse;
+}
+
+void ConvolverSound::setImpulseResponse(std::shared_ptr<ImpulseResponse> impulseResponse)
+{
+ m_impulseResponse = impulseResponse;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Delay.cpp b/extern/audaspace/src/fx/Delay.cpp
new file mode 100644
index 00000000000..e2a82299bc0
--- /dev/null
+++ b/extern/audaspace/src/fx/Delay.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Delay.h"
+#include "fx/DelayReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Delay::Delay(std::shared_ptr<ISound> sound, float delay) :
+ Effect(sound),
+ m_delay(delay)
+{
+}
+
+float Delay::getDelay() const
+{
+ return m_delay;
+}
+
+std::shared_ptr<IReader> Delay::createReader()
+{
+ return std::shared_ptr<IReader>(new DelayReader(getReader(), m_delay));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DelayReader.cpp b/extern/audaspace/src/fx/DelayReader.cpp
new file mode 100644
index 00000000000..530aed69cba
--- /dev/null
+++ b/extern/audaspace/src/fx/DelayReader.cpp
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/DelayReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+DelayReader::DelayReader(std::shared_ptr<IReader> reader, float delay) :
+ EffectReader(reader),
+ m_delay(int((SampleRate)delay * reader->getSpecs().rate)),
+ m_remdelay(int((SampleRate)delay * reader->getSpecs().rate))
+{
+}
+
+void 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 DelayReader::getLength() const
+{
+ int len = m_reader->getLength();
+ if(len < 0)
+ return len;
+ return len + m_delay;
+}
+
+int DelayReader::getPosition() const
+{
+ if(m_remdelay > 0)
+ return m_delay - m_remdelay;
+ return m_reader->getPosition() + m_delay;
+}
+
+void DelayReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(m_remdelay > 0)
+ {
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ if(length > m_remdelay)
+ {
+ std::memset(buffer, 0, m_remdelay * samplesize);
+
+ int len = length - m_remdelay;
+ m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
+
+ length = m_remdelay + len;
+
+ m_remdelay = 0;
+ }
+ else
+ {
+ std::memset(buffer, 0, length * samplesize);
+ m_remdelay -= length;
+ }
+ }
+ else
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicIIRFilter.cpp b/extern/audaspace/src/fx/DynamicIIRFilter.cpp
new file mode 100644
index 00000000000..02a8b0b65ac
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicIIRFilter.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/DynamicIIRFilter.h"
+#include "fx/DynamicIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+DynamicIIRFilter::DynamicIIRFilter(std::shared_ptr<ISound> sound,
+ std::shared_ptr<IDynamicIIRFilterCalculator> calculator) :
+ Effect(sound),
+ m_calculator(calculator)
+{
+}
+
+std::shared_ptr<IReader> DynamicIIRFilter::createReader()
+{
+ return std::shared_ptr<IReader>(new DynamicIIRFilterReader(getReader(), m_calculator));
+}
+
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp b/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp
new file mode 100644
index 00000000000..948b467aaa4
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/DynamicIIRFilterReader.h"
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+DynamicIIRFilterReader::DynamicIIRFilterReader(std::shared_ptr<IReader> reader, std::shared_ptr<IDynamicIIRFilterCalculator> calculator) :
+ IIRFilterReader(reader, std::vector<float>(), std::vector<float>()),
+ m_calculator(calculator)
+{
+ sampleRateChanged(reader->getSpecs().rate);
+}
+
+void DynamicIIRFilterReader::sampleRateChanged(SampleRate rate)
+{
+ std::vector<float> a, b;
+ m_calculator->recalculateCoefficients(rate, b, a);
+ setCoefficients(b, a);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicMusic.cpp b/extern/audaspace/src/fx/DynamicMusic.cpp
new file mode 100644
index 00000000000..b77cd749576
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicMusic.cpp
@@ -0,0 +1,346 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/DynamicMusic.h"
+#include "generator/Silence.h"
+#include "fx/Fader.h"
+#include "fx/Limiter.h"
+
+#include <mutex>
+#include <condition_variable>
+
+AUD_NAMESPACE_BEGIN
+
+DynamicMusic::DynamicMusic(std::shared_ptr<IDevice> device) :
+m_device(device), m_fadeTime(1.0f)
+{
+ m_id = 0;
+ m_transitioning = false;
+ m_stopThread = false;
+ m_volume = m_device->getVolume();
+ m_scenes.push_back(std::vector<std::shared_ptr<ISound>>(1, nullptr));
+}
+
+DynamicMusic::~DynamicMusic()
+{
+ stop();
+}
+
+int DynamicMusic::addScene(std::shared_ptr<ISound> sound)
+{
+ std::vector<std::shared_ptr<ISound>> v;
+ m_scenes.push_back(v);
+ for(int i = 0; i < m_scenes.size()-1; i++)
+ m_scenes.back().push_back(nullptr);
+ for(int i = 0; i < m_scenes.size()-1; i++)
+ m_scenes[i].push_back(nullptr);
+ m_scenes.back().push_back(sound);
+
+ return m_scenes.size() - 1;
+}
+
+bool DynamicMusic::changeScene(int id)
+{
+ if(id >= m_scenes.size() || m_transitioning)
+ return false;
+ else
+ {
+ if(m_fadeThread.joinable())
+ m_fadeThread.join();
+ m_device->lock();
+ if(id == m_id)
+ {
+ m_currentHandle->setVolume(m_volume);
+ m_currentHandle->setLoopCount(-1);
+ }
+ else
+ {
+ m_soundTarget = id;
+ if(m_scenes[m_id][id] == nullptr)
+ {
+ m_stopThread = false;
+ if((m_scenes[m_id][m_id] != nullptr && m_currentHandle->getStatus() != STATUS_INVALID) || m_scenes[m_soundTarget][m_soundTarget] != nullptr)
+ {
+ m_transitioning = true;
+ if(m_scenes[m_id][m_id] == nullptr || m_currentHandle->getStatus() == STATUS_INVALID)
+ {
+ m_device->lock();
+ m_currentHandle = m_device->play(m_scenes[m_soundTarget][m_soundTarget]);
+ m_currentHandle->setVolume(0.0f);
+ m_currentHandle->setLoopCount(-1);
+ m_device->unlock();
+ m_fadeThread = std::thread(&DynamicMusic::fadeInThread, this);
+ }
+ else
+ {
+ if(m_scenes[m_soundTarget][m_soundTarget] != nullptr)
+ {
+ m_device->lock();
+ m_transitionHandle = m_currentHandle;
+ m_currentHandle = m_device->play(m_scenes[m_soundTarget][m_soundTarget]);
+ m_currentHandle->setVolume(0.0f);
+ m_currentHandle->setLoopCount(-1);
+ m_device->unlock();
+ m_fadeThread = std::thread(&DynamicMusic::crossfadeThread, this);
+ }
+ else
+ {
+ m_transitionHandle = m_currentHandle;
+ m_currentHandle = nullptr;
+ m_fadeThread = std::thread(&DynamicMusic::fadeOutThread, this);
+ }
+ }
+ }
+ }
+ else
+ {
+ if(m_scenes[m_id][m_id] == nullptr || m_currentHandle->getStatus() == STATUS_INVALID)
+ transitionCallback(this);
+ else
+ {
+ m_currentHandle->setLoopCount(0);
+ m_currentHandle->setStopCallback(transitionCallback, this);
+ }
+ }
+ }
+ m_device->unlock();
+ return true;
+ }
+}
+
+int DynamicMusic::getScene()
+{
+ return m_id;
+}
+
+bool DynamicMusic::addTransition(int init, int end, std::shared_ptr<ISound> sound)
+{
+ if(init != end && init < m_scenes.size() && end < m_scenes.size() && init >= 0 && end >= 0)
+ {
+ m_scenes[init][end] = sound;
+ return true;
+ }
+ return false;
+}
+
+void DynamicMusic::setFadeTime(float seconds)
+{
+ m_device->lock();
+ m_fadeTime = seconds;
+ m_device->unlock();
+}
+
+float DynamicMusic::getFadeTime()
+{
+ return m_fadeTime;
+}
+
+bool DynamicMusic::resume()
+{
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->resume();
+ if(m_transitionHandle != nullptr)
+ resultTrans = m_transitionHandle->resume();
+
+ return result || resultTrans;
+}
+
+bool DynamicMusic::pause()
+{
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->pause();
+ if(m_transitionHandle != nullptr)
+ resultTrans = m_transitionHandle->pause();
+
+ return result || resultTrans;
+}
+
+bool DynamicMusic::seek(float position)
+{
+ bool result;
+
+ if(m_currentHandle != nullptr)
+ {
+ result = m_currentHandle->seek(position);
+ if(m_transitionHandle != nullptr && result == true)
+ m_transitionHandle->stop();
+ }
+
+ return result;
+}
+
+float DynamicMusic::getPosition()
+{
+ float result = 0.0f;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->getPosition();
+
+ return result;
+}
+
+float DynamicMusic::getVolume()
+{
+ return m_volume;
+}
+
+bool DynamicMusic::setVolume(float volume)
+{
+ m_volume = volume;
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->setVolume(volume);
+ if(m_transitionHandle != nullptr)
+ {
+ m_device->lock();
+ if(volume<m_transitionHandle->getVolume())
+ resultTrans = m_transitionHandle->setVolume(0.0f);
+ m_device->unlock();
+ }
+ if(m_currentHandle == nullptr && m_transitionHandle == nullptr)
+ result = true;
+
+ return result || resultTrans;
+}
+
+Status DynamicMusic::getStatus()
+{
+ if(m_currentHandle != nullptr)
+ {
+ Status result = m_currentHandle->getStatus();
+ return result;
+ }
+ else
+ return STATUS_INVALID;
+}
+
+bool DynamicMusic::stop()
+{
+ m_stopThread = true;
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->stop();
+ if(m_transitionHandle != nullptr)
+
+ resultTrans = m_transitionHandle->stop();
+
+ if(m_fadeThread.joinable())
+ m_fadeThread.join();
+ m_id = 0;
+
+ return result || resultTrans;
+}
+
+void DynamicMusic::transitionCallback(void* player)
+{
+ auto dat = reinterpret_cast<DynamicMusic*>(player);
+ dat->m_transitioning = true;
+ dat->m_device->lock();
+ dat->m_currentHandle = dat->m_device->play(dat->m_scenes[dat->m_id][dat->m_soundTarget]);
+ dat->m_currentHandle->setVolume(dat->m_volume);
+ if(dat->m_scenes[dat->m_soundTarget][dat->m_soundTarget] != nullptr)
+ dat->m_currentHandle->setStopCallback(sceneCallback, player);
+ dat->m_device->unlock();
+}
+
+void DynamicMusic::sceneCallback(void* player)
+{
+ auto dat = reinterpret_cast<DynamicMusic*>(player);
+ dat->m_device->lock();
+ dat->m_currentHandle = dat->m_device->play(dat->m_scenes[dat->m_soundTarget][dat->m_soundTarget]);
+ dat->m_currentHandle->setVolume(dat->m_volume);
+ dat->m_currentHandle->setLoopCount(-1);
+ dat->m_device->unlock();
+ dat->m_id = int(dat->m_soundTarget);
+ dat->m_soundTarget = -1;
+ dat->m_transitioning = false;
+}
+
+void DynamicMusic::crossfadeThread()
+{
+ float currentVol = m_transitionHandle->getVolume();
+ float nextVol = m_currentHandle->getVolume();
+ float increment;
+
+ while(nextVol < m_volume && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ currentVol -= increment;
+ nextVol += increment;
+ if(currentVol < 0)
+ currentVol = 0;
+ if(nextVol > m_volume)
+ nextVol = m_volume;
+ m_transitionHandle->setVolume(currentVol);
+ m_currentHandle->setVolume(nextVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+ if(m_stopThread)
+ m_transitionHandle->setVolume(m_volume);
+
+ m_transitionHandle->stop();
+
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+
+void DynamicMusic::fadeInThread()
+{
+ float nextVol = m_currentHandle->getVolume();
+ float increment;
+
+ while(nextVol < m_volume && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ nextVol += increment;
+ if(nextVol > m_volume)
+ nextVol = m_volume;
+ m_currentHandle->setVolume(nextVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+ if(m_stopThread)
+ m_currentHandle->setVolume(m_volume);
+
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+
+void DynamicMusic::fadeOutThread()
+{
+ float currentVol = m_transitionHandle->getVolume();
+ float increment;
+
+ while(currentVol > 0.0f && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ currentVol -= increment;
+ if(currentVol < 0)
+ currentVol = 0;
+ m_transitionHandle->setVolume(currentVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+
+ m_transitionHandle->stop();
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Effect.cpp b/extern/audaspace/src/fx/Effect.cpp
new file mode 100644
index 00000000000..af59ba440f9
--- /dev/null
+++ b/extern/audaspace/src/fx/Effect.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+Effect::Effect(std::shared_ptr<ISound> sound)
+{
+ m_sound = sound;
+}
+
+Effect::~Effect()
+{
+}
+
+std::shared_ptr<ISound> Effect::getSound() const
+{
+ return m_sound;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/EffectReader.cpp b/extern/audaspace/src/fx/EffectReader.cpp
new file mode 100644
index 00000000000..93a9d3cbf1c
--- /dev/null
+++ b/extern/audaspace/src/fx/EffectReader.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+EffectReader::EffectReader(std::shared_ptr<IReader> reader)
+{
+ m_reader = reader;
+}
+
+EffectReader::~EffectReader()
+{
+}
+
+bool EffectReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void EffectReader::seek(int position)
+{
+ m_reader->seek(position);
+}
+
+int EffectReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int EffectReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs EffectReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void EffectReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Envelope.cpp b/extern/audaspace/src/fx/Envelope.cpp
new file mode 100644
index 00000000000..0637706c0a9
--- /dev/null
+++ b/extern/audaspace/src/fx/Envelope.cpp
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Envelope.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+struct EnvelopeParameters
+{
+ float attack;
+ float release;
+ float threshold;
+ float arthreshold;
+};
+
+sample_t Envelope::envelopeFilter(CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+{
+ float in = std::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 Envelope::endEnvelopeFilter(EnvelopeParameters* param)
+{
+ delete param;
+}
+
+Envelope::Envelope(std::shared_ptr<ISound> sound, float attack, float release, float threshold, float arthreshold) :
+ Effect(sound),
+ m_attack(attack),
+ m_release(release),
+ m_threshold(threshold),
+ m_arthreshold(arthreshold)
+{
+}
+
+std::shared_ptr<IReader> Envelope::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+
+ EnvelopeParameters* param = new EnvelopeParameters();
+ param->arthreshold = m_arthreshold;
+ param->attack = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
+ param->release = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
+ param->threshold = m_threshold;
+
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(reader, 1, 2,
+ (doFilterIIR) envelopeFilter,
+ (endFilterIIR) endEnvelopeFilter,
+ param));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/FFTConvolver.cpp b/extern/audaspace/src/fx/FFTConvolver.cpp
new file mode 100644
index 00000000000..868a1ebbaf3
--- /dev/null
+++ b/extern/audaspace/src/fx/FFTConvolver.cpp
@@ -0,0 +1,214 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/FFTConvolver.h"
+
+#include <cstring>
+#include <cstdlib>
+
+AUD_NAMESPACE_BEGIN
+
+FFTConvolver::FFTConvolver(std::shared_ptr<std::vector<std::complex<sample_t>>> ir, std::shared_ptr<FFTPlan> plan) :
+ m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_tailPos(0), m_irBuffer(ir)
+{
+ m_tail = (float*)calloc(m_M - 1, sizeof(float));
+ m_realBufLen = ((m_N / 2) + 1) * 2;
+ m_inBuffer = nullptr;
+ m_shiftBuffer = (sample_t*)std::calloc(m_N, sizeof(sample_t));
+}
+
+FFTConvolver::~FFTConvolver()
+{
+ std::free(m_tail);
+ std::free(m_shiftBuffer);
+ if(m_inBuffer != nullptr)
+ m_plan->freeBuffer(m_inBuffer);
+}
+
+void FFTConvolver::getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, length*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length, fftwf_complex* transformedData)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, length*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ std::memcpy(transformedData, m_inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getNext(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getTail(int& length, bool& eos, sample_t* buffer)
+{
+ if(length <= 0)
+ {
+ length = 0;
+ eos = m_tailPos >= m_M - 1;
+ return;
+ }
+
+ eos = false;
+ if(m_tailPos + length > m_M - 1)
+ {
+ length = m_M - 1 - m_tailPos;
+ if(length < 0)
+ length = 0;
+ eos = true;
+ m_tailPos = m_M - 1;
+ }
+ else
+ m_tailPos += length;
+ std::memcpy(buffer, m_tail, length*sizeof(sample_t));
+}
+
+void FFTConvolver::clear()
+{
+ std::memset(m_shiftBuffer, 0, m_N * sizeof(sample_t));
+ std::memset(m_tail, 0, m_M - 1);
+}
+
+void FFTConvolver::IFFT_FDL(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ m_plan->IFFT(m_inBuffer);
+ std::memcpy(outBuffer, ((sample_t*)m_inBuffer)+m_L, length*sizeof(sample_t));
+}
+
+void FFTConvolver::getNextFDL(const std::complex<sample_t>* inBuffer, std::complex<sample_t>* accBuffer)
+{
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ accBuffer[i] += (inBuffer[i] * (*m_irBuffer)[i]) / sample_t(m_N);
+ }
+}
+
+void FFTConvolver::getNextFDL(const sample_t* inBuffer, std::complex<sample_t>* accBuffer, int& length, fftwf_complex* transformedData)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memcpy(m_shiftBuffer, m_shiftBuffer + m_L, m_L*sizeof(sample_t));
+ std::memcpy(m_shiftBuffer + m_L, inBuffer, length*sizeof(sample_t));
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, m_shiftBuffer, (m_L+length)*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ std::memcpy(transformedData, m_inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ accBuffer[i] += (m_inBuffer[i] * (*m_irBuffer)[i]) / sample_t(m_N);
+ }
+}
+
+
+void FFTConvolver::setImpulseResponse(std::shared_ptr<std::vector<std::complex<sample_t>>> ir)
+{
+ clear();
+ m_irBuffer = ir;
+}
+
+std::shared_ptr<std::vector<std::complex<sample_t>>> FFTConvolver::getImpulseResponse()
+{
+ return m_irBuffer;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Fader.cpp b/extern/audaspace/src/fx/Fader.cpp
new file mode 100644
index 00000000000..041d8369a01
--- /dev/null
+++ b/extern/audaspace/src/fx/Fader.cpp
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Fader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Fader::Fader(std::shared_ptr<ISound> sound, FadeType type, float start, float length) :
+ Effect(sound),
+ m_type(type),
+ m_start(start),
+ m_length(length)
+{
+}
+
+FadeType Fader::getType() const
+{
+ return m_type;
+}
+
+float Fader::getStart() const
+{
+ return m_start;
+}
+
+float Fader::getLength() const
+{
+ return m_length;
+}
+
+std::shared_ptr<IReader> Fader::createReader()
+{
+ return std::shared_ptr<IReader>(new FaderReader(getReader(), m_type, m_start, m_length));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/FaderReader.cpp b/extern/audaspace/src/fx/FaderReader.cpp
new file mode 100644
index 00000000000..b1e23b993f3
--- /dev/null
+++ b/extern/audaspace/src/fx/FaderReader.cpp
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/FaderReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+FaderReader::FaderReader(std::shared_ptr<IReader> reader, FadeType type, float start,float length) :
+ EffectReader(reader),
+ m_type(type),
+ m_start(start),
+ m_length(length)
+{
+}
+
+void FaderReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int position = m_reader->getPosition();
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_reader->read(length, eos, buffer);
+
+ if((position + length) / (float)specs.rate <= m_start)
+ {
+ if(m_type != FADE_OUT)
+ {
+ std::memset(buffer, 0, length * samplesize);
+ }
+ }
+ else if(position / (float)specs.rate >= m_start+m_length)
+ {
+ if(m_type == FADE_OUT)
+ {
+ std::memset(buffer, 0, length * samplesize);
+ }
+ }
+ else
+ {
+ 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 == FADE_OUT)
+ volume = 1.0f - volume;
+ }
+
+ buffer[i] = buffer[i] * volume;
+ }
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HRTF.cpp b/extern/audaspace/src/fx/HRTF.cpp
new file mode 100644
index 00000000000..14ef3ad0912
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTF.cpp
@@ -0,0 +1,122 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/HRTF.h"
+#include "Exception.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+HRTF::HRTF() :
+ HRTF(std::make_shared<FFTPlan>(0.0))
+{
+}
+
+HRTF::HRTF(std::shared_ptr<FFTPlan> plan) :
+ m_plan(plan)
+{
+ m_specs.channels = CHANNELS_INVALID;
+ m_specs.rate = 0;
+ m_empty = true;
+}
+
+bool HRTF::addImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, float azimuth, float elevation)
+{
+ Specs spec = impulseResponse->getSpecs();
+
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+
+ if((spec.channels != CHANNELS_MONO) || (spec.rate != m_specs.rate && m_specs.rate > 0.0))
+ return false;
+
+ m_hrtfs[elevation][azimuth] = std::make_shared<ImpulseResponse>(impulseResponse, m_plan);
+ m_specs.channels = CHANNELS_MONO;
+ m_specs.rate = spec.rate;
+ m_empty = false;
+ return true;
+}
+
+std::pair<std::shared_ptr<ImpulseResponse>, std::shared_ptr<ImpulseResponse>> HRTF::getImpulseResponse(float &azimuth, float &elevation)
+{
+ if(m_hrtfs.empty())
+ return std::make_pair(nullptr, nullptr);
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+
+ std::shared_ptr<ImpulseResponse> R, L;
+ float az = 0, el = 0, dif=0, minDif=360;
+
+ for(auto elem : m_hrtfs)
+ {
+ dif = std::fabs(elevation - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ el = elem.first;
+ }
+ }
+ elevation = el;
+ dif = 0;
+ minDif = 360;
+
+ for(auto elem : m_hrtfs[elevation])
+ {
+ dif = std::fabs(azimuth - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ az = elem.first;
+ R = elem.second;
+ }
+ }
+ azimuth = az;
+ float azL = 360 - azimuth;
+ if(azL == 360)
+ azL = 0;
+
+ auto iter = m_hrtfs[elevation].find(azL);
+ if(iter != m_hrtfs[elevation].end())
+ L = iter->second;
+ else
+ {
+ dif = 0;
+ minDif = 360;
+ for(auto elem : m_hrtfs[elevation])
+ {
+ dif = std::fabs(azL - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ L = elem.second;
+ }
+ }
+ }
+ return std::make_pair(L, R);
+}
+
+Specs HRTF::getSpecs()
+{
+ return m_specs;
+}
+
+bool HRTF::isEmpty()
+{
+ return m_empty;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HRTFLoaderUnix.cpp b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp
new file mode 100644
index 00000000000..12a23913912
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/HRTFLoader.h"
+#include "file/File.h"
+#include "Exception.h"
+
+#include <dirent.h>
+#include <exception>
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::string& fileExtension, const std::string& path)
+{
+ std::string readpath = path;
+ if(path == "")
+ readpath = ".";
+
+ DIR* dir = opendir(path.c_str());
+ if(!dir)
+ return;
+
+ float azim, elev;
+
+ while(dirent* entry = readdir(dir))
+ {
+ std::string filename = entry->d_name;
+ if(filename.front() == ear && filename.length() >= fileExtension.length() && filename.substr(filename.length() - fileExtension.length()) == fileExtension)
+ {
+ try
+ {
+ elev = std::stof(filename.substr(1, filename.find("e") - 1));
+ azim = std::stof(filename.substr(filename.find("e") + 1, filename.find("a") - filename.find("e") - 1));
+ if(ear == 'L')
+ azim = 360 - azim;
+ }
+ catch(std::exception& e)
+ {
+ AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
+ }
+ hrtfs->addImpulseResponse(std::make_shared<StreamBuffer>(std::make_shared<File>(readpath + "/" + filename)), azim, elev);
+ }
+ }
+ closedir(dir);
+ return;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/HRTFLoaderWindows.cpp b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp
new file mode 100644
index 00000000000..148f1fa015d
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/HRTFLoader.h"
+#include "file/File.h"
+#include "Exception.h"
+
+#include <windows.h>
+#include <exception>
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::string& fileExtension, const std::string& path)
+{
+ std::string readpath = path;
+ if(path == "")
+ readpath = ".";
+
+ WIN32_FIND_DATA entry;
+ bool found_file = true;
+ std::string search = readpath + "\\*";
+ HANDLE dir = FindFirstFile(search.c_str(), &entry);
+ if(dir == INVALID_HANDLE_VALUE)
+ return;
+
+ float azim, elev;
+
+ while(found_file)
+ {
+ std::string filename = entry.cFileName;
+ if(filename.front() == ear && filename.length() >= fileExtension.length() && filename.substr(filename.length() - fileExtension.length()) == fileExtension)
+ {
+ try
+ {
+ elev = std::stof(filename.substr(1, filename.find("e") - 1));
+ azim = std::stof(filename.substr(filename.find("e") + 1, filename.find("a") - filename.find("e") - 1));
+ if(ear == 'L')
+ azim = 360 - azim;
+ }
+ catch(std::exception& e)
+ {
+ AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
+ }
+ hrtfs->addImpulseResponse(std::make_shared<StreamBuffer>(std::make_shared<File>(readpath + "/" + filename)), azim, elev);
+ }
+ found_file = FindNextFile(dir, &entry);
+ }
+ FindClose(dir);
+ return;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Highpass.cpp b/extern/audaspace/src/fx/Highpass.cpp
new file mode 100644
index 00000000000..2490d512078
--- /dev/null
+++ b/extern/audaspace/src/fx/Highpass.cpp
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Highpass.h"
+#include "fx/IIRFilterReader.h"
+#include "fx/HighpassCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Highpass::Highpass(std::shared_ptr<ISound> sound, float frequency, float Q) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new HighpassCalculator(frequency, Q)))
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HighpassCalculator.cpp b/extern/audaspace/src/fx/HighpassCalculator.cpp
new file mode 100644
index 00000000000..2b69efe2fa7
--- /dev/null
+++ b/extern/audaspace/src/fx/HighpassCalculator.cpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/HighpassCalculator.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+HighpassCalculator::HighpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void HighpassCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2.0 * M_PI * (SampleRate)m_frequency / rate;
+ float alpha = (float)(std::sin(w0) / (2.0 * (double)m_Q));
+ float norm = 1 + alpha;
+ float c = std::cos(w0);
+ 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]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/IIRFilter.cpp b/extern/audaspace/src/fx/IIRFilter.cpp
new file mode 100644
index 00000000000..fce6d01e4bf
--- /dev/null
+++ b/extern/audaspace/src/fx/IIRFilter.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/IIRFilter.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+IIRFilter::IIRFilter(std::shared_ptr<ISound> sound, const std::vector<float>& b, const std::vector<float>& a) :
+ Effect(sound), m_a(a), m_b(b)
+{
+}
+
+std::shared_ptr<IReader> IIRFilter::createReader()
+{
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), m_b, m_a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/IIRFilterReader.cpp b/extern/audaspace/src/fx/IIRFilterReader.cpp
new file mode 100644
index 00000000000..8d879a85846
--- /dev/null
+++ b/extern/audaspace/src/fx/IIRFilterReader.cpp
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+IIRFilterReader::IIRFilterReader(std::shared_ptr<IReader> reader, const std::vector<float>& b, const std::vector<float>& a) :
+ BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
+{
+ if(m_a.empty() == false)
+ {
+ 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 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;
+}
+
+void IIRFilterReader::setCoefficients(const std::vector<float>& b, const std::vector<float>& a)
+{
+ setLengths(b.size(), a.size());
+ m_a = a;
+ m_b = b;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ImpulseResponse.cpp b/extern/audaspace/src/fx/ImpulseResponse.cpp
new file mode 100644
index 00000000000..babb628eb7a
--- /dev/null
+++ b/extern/audaspace/src/fx/ImpulseResponse.cpp
@@ -0,0 +1,97 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/ImpulseResponse.h"
+
+#include <algorithm>
+#include <cstring>
+#include <cstdlib>
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+ImpulseResponse::ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse) :
+ ImpulseResponse(impulseResponse, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+ImpulseResponse::ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, std::shared_ptr<FFTPlan> plan)
+{
+ auto reader = impulseResponse->createReader();
+ m_length = reader->getLength();
+ processImpulseResponse(impulseResponse->createReader(), plan);
+}
+
+Specs ImpulseResponse::getSpecs()
+{
+ return m_specs;
+}
+
+int ImpulseResponse::getLength()
+{
+ return m_length;
+}
+
+std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ImpulseResponse::getChannel(int n)
+{
+ return m_processedIR[n];
+}
+
+void ImpulseResponse::processImpulseResponse(std::shared_ptr<IReader> reader, std::shared_ptr<FFTPlan> plan)
+{
+ m_specs.channels = reader->getSpecs().channels;
+ m_specs.rate = reader->getSpecs().rate;
+ int N = plan->getSize();
+ bool eos = false;
+ int length = reader->getLength();
+ sample_t* buffer = (sample_t*)std::malloc(length * m_specs.channels * sizeof(sample_t));
+ int numParts = std::ceil((float)length / (plan->getSize() / 2));
+
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ m_processedIR.push_back(std::make_shared<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>>());
+ for(int j = 0; j < numParts; j++)
+ (*m_processedIR[i]).push_back(std::make_shared<std::vector<std::complex<sample_t>>>((N / 2) + 1));
+ }
+ length += reader->getSpecs().rate;
+ reader->read(length, eos, buffer);
+
+
+ void* bufferFFT = plan->getBuffer();
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ int partStart = 0;
+ for(int h = 0; h < numParts; h++)
+ {
+ int k = 0;
+ int len = std::min(partStart + ((N / 2)*m_specs.channels), length*m_specs.channels);
+ std::memset(bufferFFT, 0, ((N / 2) + 1) * 2 * sizeof(fftwf_complex));
+ for(int j = partStart; j < len; j += m_specs.channels)
+ {
+ ((float*)bufferFFT)[k] = buffer[j + i];
+ k++;
+ }
+ plan->FFT(bufferFFT);
+ for(int j = 0; j < (N / 2) + 1; j++)
+ {
+ (*(*m_processedIR[i])[h])[j] = reinterpret_cast<std::complex<sample_t>*>(bufferFFT)[j];
+ }
+ partStart += N / 2 * m_specs.channels;
+ }
+ }
+ plan->freeBuffer(bufferFFT);
+ std::free(buffer);
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Limiter.cpp b/extern/audaspace/src/fx/Limiter.cpp
new file mode 100644
index 00000000000..38a7288e8d7
--- /dev/null
+++ b/extern/audaspace/src/fx/Limiter.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Limiter.h"
+#include "fx/LimiterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Limiter::Limiter(std::shared_ptr<ISound> sound,
+ float start, float end) :
+ Effect(sound),
+ m_start(start),
+ m_end(end)
+{
+}
+
+float Limiter::getStart() const
+{
+ return m_start;
+}
+
+float Limiter::getEnd() const
+{
+ return m_end;
+}
+
+std::shared_ptr<IReader> Limiter::createReader()
+{
+ return std::shared_ptr<IReader>(new LimiterReader(getReader(), m_start, m_end));
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/extern/audaspace/src/fx/LimiterReader.cpp
index 7d850ac7b5f..1d003c29679 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/extern/audaspace/src/fx/LimiterReader.cpp
@@ -1,45 +1,35 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/FX/AUD_LimiterReader.cpp
- * \ingroup audfx
- */
+#include "fx/LimiterReader.h"
+#include "util/Buffer.h"
+#include <algorithm>
-#include "AUD_LimiterReader.h"
-#include "AUD_Buffer.h"
+AUD_NAMESPACE_BEGIN
-AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
- float start, float end) :
- AUD_EffectReader(reader),
+LimiterReader::LimiterReader(std::shared_ptr<IReader> reader, float start, float end) :
+ EffectReader(reader),
m_start(start),
m_end(end)
{
if(m_start > 0)
{
- AUD_Specs specs = m_reader->getSpecs();
- AUD_Specs specs2;
+ Specs specs = m_reader->getSpecs();
+ Specs specs2;
if(m_reader->isSeekable())
m_reader->seek(m_start * specs.rate);
@@ -47,7 +37,7 @@ AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
{
// skip first m_start samples by reading them
int length = AUD_DEFAULT_BUFFER_SIZE;
- AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+ Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
bool eos = false;
for(int len = m_start * specs.rate;
length > 0 && !eos;
@@ -75,34 +65,34 @@ AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
}
}
-void AUD_LimiterReader::seek(int position)
+void LimiterReader::seek(int position)
{
m_reader->seek(position + m_start * m_reader->getSpecs().rate);
}
-int AUD_LimiterReader::getLength() const
+int LimiterReader::getLength() const
{
int len = m_reader->getLength();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
+ SampleRate rate = m_reader->getSpecs().rate;
if(len < 0 || (len > m_end * rate && m_end >= 0))
len = m_end * rate;
return len - m_start * rate;
}
-int AUD_LimiterReader::getPosition() const
+int LimiterReader::getPosition() const
{
int pos = m_reader->getPosition();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
- return AUD_MIN(pos, m_end * rate) - m_start * rate;
+ SampleRate rate = m_reader->getSpecs().rate;
+ return std::min(pos, int(m_end * rate)) - m_start * rate;
}
-void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
+void LimiterReader::read(int& length, bool& eos, sample_t* buffer)
{
eos = false;
if(m_end >= 0)
{
int position = m_reader->getPosition();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
+ SampleRate rate = m_reader->getSpecs().rate;
if(position + length > m_end * rate)
{
@@ -145,3 +135,5 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
else
m_reader->read(length, eos, buffer);
}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Loop.cpp b/extern/audaspace/src/fx/Loop.cpp
new file mode 100644
index 00000000000..1695fcf1662
--- /dev/null
+++ b/extern/audaspace/src/fx/Loop.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Loop.h"
+#include "fx/LoopReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Loop::Loop(std::shared_ptr<ISound> sound, int loop) :
+ Effect(sound),
+ m_loop(loop)
+{
+}
+
+int Loop::getLoop() const
+{
+ return m_loop;
+}
+
+std::shared_ptr<IReader> Loop::createReader()
+{
+ return std::shared_ptr<IReader>(new LoopReader(getReader(), m_loop));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/LoopReader.cpp b/extern/audaspace/src/fx/LoopReader.cpp
new file mode 100644
index 00000000000..2f13a5880eb
--- /dev/null
+++ b/extern/audaspace/src/fx/LoopReader.cpp
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/LoopReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+LoopReader::LoopReader(std::shared_ptr<IReader> reader, int loop) :
+ EffectReader(reader), m_count(loop), m_left(loop)
+{
+}
+
+void 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 LoopReader::getLength() const
+{
+ if(m_count < 0)
+ return -1;
+ return m_reader->getLength() * m_count;
+}
+
+int LoopReader::getPosition() const
+{
+ return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
+}
+
+void LoopReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ const Specs specs = m_reader->getSpecs();
+
+ int len = length;
+
+ m_reader->read(length, eos, buffer);
+
+ if(length < len && eos && m_left)
+ {
+ int pos = length;
+ length = len;
+
+ while(pos < length && eos && m_left)
+ {
+ if(m_left > 0)
+ m_left--;
+
+ m_reader->seek(0);
+
+ len = length - pos;
+ m_reader->read(len, eos, buffer + pos * specs.channels);
+
+ // prevent endless loop
+ if(!len)
+ break;
+
+ pos += len;
+ }
+
+ length = pos;
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Lowpass.cpp b/extern/audaspace/src/fx/Lowpass.cpp
new file mode 100644
index 00000000000..8c33291baa3
--- /dev/null
+++ b/extern/audaspace/src/fx/Lowpass.cpp
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Lowpass.h"
+#include "fx/LowpassCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Lowpass::Lowpass(std::shared_ptr<ISound> sound, float frequency, float Q) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new LowpassCalculator(frequency, Q)))
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/LowpassCalculator.cpp b/extern/audaspace/src/fx/LowpassCalculator.cpp
new file mode 100644
index 00000000000..f2a53ed7514
--- /dev/null
+++ b/extern/audaspace/src/fx/LowpassCalculator.cpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/LowpassCalculator.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+LowpassCalculator::LowpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void LowpassCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2 * M_PI * m_frequency / rate;
+ float alpha = std::sin(w0) / (2 * m_Q);
+ float norm = 1 + alpha;
+ float c = std::cos(w0);
+ 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]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/MutableReader.cpp b/extern/audaspace/src/fx/MutableReader.cpp
new file mode 100644
index 00000000000..aa867d83f03
--- /dev/null
+++ b/extern/audaspace/src/fx/MutableReader.cpp
@@ -0,0 +1,64 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/MutableReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+MutableReader::MutableReader(std::shared_ptr<ISound> sound) :
+m_sound(sound)
+{
+ m_reader = m_sound->createReader();
+}
+
+bool MutableReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void MutableReader::seek(int position)
+{
+ if(position < m_reader->getPosition())
+ {
+ m_reader = m_sound->createReader();
+ }
+ else
+ m_reader->seek(position);
+}
+
+int MutableReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int MutableReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs MutableReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void MutableReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/MutableSound.cpp b/extern/audaspace/src/fx/MutableSound.cpp
new file mode 100644
index 00000000000..5326b640394
--- /dev/null
+++ b/extern/audaspace/src/fx/MutableSound.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/MutableSound.h"
+#include "fx/MutableReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+MutableSound::MutableSound(std::shared_ptr<ISound> sound) :
+m_sound(sound)
+{
+}
+
+std::shared_ptr<IReader> MutableSound::createReader()
+{
+ return std::make_shared<MutableReader>(m_sound);
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Pitch.cpp b/extern/audaspace/src/fx/Pitch.cpp
new file mode 100644
index 00000000000..d7348a2d49e
--- /dev/null
+++ b/extern/audaspace/src/fx/Pitch.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Pitch.h"
+#include "fx/PitchReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Pitch::Pitch(std::shared_ptr<ISound> sound, float pitch) :
+ Effect(sound),
+ m_pitch(pitch)
+{
+}
+
+std::shared_ptr<IReader> Pitch::createReader()
+{
+ return std::shared_ptr<IReader>(new PitchReader(getReader(), m_pitch));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PitchReader.cpp b/extern/audaspace/src/fx/PitchReader.cpp
new file mode 100644
index 00000000000..f44be0261e6
--- /dev/null
+++ b/extern/audaspace/src/fx/PitchReader.cpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/PitchReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+PitchReader::PitchReader(std::shared_ptr<IReader> reader, float pitch) :
+ EffectReader(reader), m_pitch(pitch)
+{
+}
+
+Specs PitchReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.rate *= m_pitch;
+ return specs;
+}
+
+float PitchReader::getPitch() const
+{
+ return m_pitch;
+}
+
+void PitchReader::setPitch(float pitch)
+{
+ if(pitch > 0.0f)
+ m_pitch = pitch;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PlaybackCategory.cpp b/extern/audaspace/src/fx/PlaybackCategory.cpp
new file mode 100644
index 00000000000..e09a74c4017
--- /dev/null
+++ b/extern/audaspace/src/fx/PlaybackCategory.cpp
@@ -0,0 +1,144 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/PlaybackCategory.h"
+#include "fx/VolumeSound.h"
+
+AUD_NAMESPACE_BEGIN
+
+struct HandleData {
+ unsigned int id;
+ PlaybackCategory* category;
+};
+
+PlaybackCategory::PlaybackCategory(std::shared_ptr<IDevice> device) :
+ m_device(device), m_volumeStorage(std::make_shared<VolumeStorage>(1.0f)), m_status(STATUS_PLAYING), m_currentID(0)
+{
+}
+
+PlaybackCategory::~PlaybackCategory()
+{
+ stop();
+}
+
+std::shared_ptr<IHandle> PlaybackCategory::play(std::shared_ptr<ISound> sound)
+{
+ std::shared_ptr<ISound> vs(std::make_shared<VolumeSound>(sound, m_volumeStorage));
+ m_device->lock();
+ auto handle = m_device->play(vs);
+ if(handle == nullptr)
+ return nullptr;
+ switch (m_status)
+ {
+ case STATUS_PAUSED:
+ handle->pause();
+ break;
+ default:
+ m_status = STATUS_PLAYING;
+ };
+ m_handles[m_currentID] = handle;
+ HandleData* data = new HandleData;
+ data->category = this;
+ data->id = m_currentID;
+ handle->setStopCallback(cleanHandleCallback, data);
+ m_device->unlock();
+
+ m_currentID++;
+ return handle;
+}
+
+void PlaybackCategory::resume()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ {
+ i->second->resume();
+ i++;
+ }
+ }
+ m_device->unlock();
+ m_status = STATUS_PLAYING;
+}
+
+void PlaybackCategory::pause()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ {
+ i->second->pause();
+ i++;
+ }
+ }
+ m_device->unlock();
+ m_status = STATUS_PAUSED;
+}
+
+float PlaybackCategory::getVolume()
+{
+ return m_volumeStorage->getVolume();
+}
+
+void PlaybackCategory::setVolume(float volume)
+{
+ m_volumeStorage->setVolume(volume);
+}
+
+void PlaybackCategory::stop()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ i->second->stop();
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ i++;
+ }
+ m_device->unlock();
+ m_status = STATUS_STOPPED;
+}
+
+std::shared_ptr<VolumeStorage> PlaybackCategory::getSharedVolume()
+{
+ return m_volumeStorage;
+}
+
+void PlaybackCategory::cleanHandles()
+{
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ i++;
+ }
+}
+
+void PlaybackCategory::cleanHandleCallback(void* data)
+{
+ auto dat = reinterpret_cast<HandleData*>(data);
+ dat->category->m_handles.erase(dat->id);
+ delete dat;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PlaybackManager.cpp b/extern/audaspace/src/fx/PlaybackManager.cpp
new file mode 100644
index 00000000000..0fbeeba04e2
--- /dev/null
+++ b/extern/audaspace/src/fx/PlaybackManager.cpp
@@ -0,0 +1,186 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/PlaybackManager.h"
+#include "fx/VolumeSound.h"
+
+#include <stdexcept>
+
+AUD_NAMESPACE_BEGIN
+PlaybackManager::PlaybackManager(std::shared_ptr<IDevice> device) :
+ m_device(device), m_currentKey(0)
+{
+}
+
+unsigned int PlaybackManager::addCategory(std::shared_ptr<PlaybackCategory> category)
+{
+ bool flag = true;
+ unsigned int k = -1;
+ do {
+ auto iter = m_categories.find(m_currentKey);
+ if(iter == m_categories.end())
+ {
+ m_categories[m_currentKey] = category;
+ k = m_currentKey;
+ m_currentKey++;
+ flag = false;
+ }
+ else
+ m_currentKey++;
+ } while(flag);
+
+ return k;
+}
+
+unsigned int PlaybackManager::addCategory(float volume)
+{
+ std::shared_ptr<PlaybackCategory> category = std::make_shared<PlaybackCategory>(m_device);
+ category->setVolume(volume);
+ bool flag = true;
+ unsigned int k = -1;
+ do {
+ auto iter = m_categories.find(m_currentKey);
+ if(iter == m_categories.end())
+ {
+ m_categories[m_currentKey] = category;
+ k = m_currentKey;
+ m_currentKey++;
+ flag = false;
+ }
+ else
+ m_currentKey++;
+ } while(flag);
+
+ return k;
+}
+
+std::shared_ptr<IHandle> PlaybackManager::play(std::shared_ptr<ISound> sound, unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+ std::shared_ptr<PlaybackCategory> category;
+
+ if(iter != m_categories.end())
+ {
+ category = iter->second;
+ }
+ else
+ {
+ category = std::make_shared<PlaybackCategory>(m_device);
+ m_categories[catKey] = category;
+ }
+ return category->play(sound);
+}
+
+bool PlaybackManager::resume(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->resume();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PlaybackManager::pause(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->pause();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+float PlaybackManager::getVolume(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ return iter->second->getVolume();
+ }
+ else
+ {
+ return -1.0;
+ }
+}
+
+bool PlaybackManager::setVolume(float volume, unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->setVolume(volume);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PlaybackManager::stop(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->stop();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void PlaybackManager::clean()
+{
+ for(auto cat : m_categories)
+ cat.second->cleanHandles();
+}
+
+bool PlaybackManager::clean(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->cleanHandles();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+std::shared_ptr<IDevice> PlaybackManager::getDevice()
+{
+ return m_device;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Reverse.cpp b/extern/audaspace/src/fx/Reverse.cpp
new file mode 100644
index 00000000000..7d906056071
--- /dev/null
+++ b/extern/audaspace/src/fx/Reverse.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Reverse.h"
+#include "fx/ReverseReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Reverse::Reverse(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> Reverse::createReader()
+{
+ return std::shared_ptr<IReader>(new ReverseReader(getReader()));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ReverseReader.cpp b/extern/audaspace/src/fx/ReverseReader.cpp
new file mode 100644
index 00000000000..19a1e25ce4f
--- /dev/null
+++ b/extern/audaspace/src/fx/ReverseReader.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/ReverseReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ReverseReader::ReverseReader(std::shared_ptr<IReader> reader) :
+ EffectReader(reader),
+ m_length(reader->getLength()),
+ m_position(0)
+{
+ if(m_length < 0 || !reader->isSeekable())
+ AUD_THROW(StateException, "A reader has to be seekable and have finite length to be reversible.");
+}
+
+void ReverseReader::seek(int position)
+{
+ m_position = position;
+}
+
+int ReverseReader::getLength() const
+{
+ return m_length;
+}
+
+int ReverseReader::getPosition() const
+{
+ return m_position;
+}
+
+void ReverseReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // first correct the length
+ if(m_position + length > m_length)
+ length = m_length - m_position;
+
+ if(length <= 0)
+ {
+ length = 0;
+ eos = true;
+ return;
+ }
+
+ const Specs specs = getSpecs();
+ const int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ sample_t temp[CHANNEL_MAX];
+
+ int len = length;
+
+ // read from reader
+ m_reader->seek(m_length - m_position - len);
+ m_reader->read(len, eos, buffer);
+
+ // set null if reader didn't give enough data
+ if(len < length)
+ std::memset(buffer, 0, (length - len) * samplesize);
+
+ // copy the samples reverted
+ for(int i = 0; i < length / 2; i++)
+ {
+ std::memcpy(temp, buffer + (len - 1 - i) * specs.channels, samplesize);
+ std::memcpy(buffer + (len - 1 - i) * specs.channels, buffer + i * specs.channels, samplesize);
+ std::memcpy(buffer + i * specs.channels, temp, samplesize);
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/SoundList.cpp b/extern/audaspace/src/fx/SoundList.cpp
new file mode 100644
index 00000000000..81239ca5baa
--- /dev/null
+++ b/extern/audaspace/src/fx/SoundList.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/SoundList.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <chrono>
+
+AUD_NAMESPACE_BEGIN
+
+SoundList::SoundList(bool random) :
+m_random(random)
+{
+ std::srand(time(NULL));
+}
+
+SoundList::SoundList(std::vector<std::shared_ptr<ISound>>& list, bool random) :
+m_list(list), m_random(random)
+{
+ std::srand(time(NULL));
+}
+
+std::shared_ptr<IReader> SoundList::createReader()
+{
+ if(m_list.size() > 0)
+ {
+ m_mutex.lock();
+
+ if(!m_random){
+ m_index++;
+ if(m_index >= m_list.size())
+ m_index = 0;
+ }
+ else
+ {
+ int temp;
+ do{
+ temp = std::rand() % m_list.size();
+ } while(temp == m_index && m_list.size()>1);
+ m_index = temp;
+ }
+ auto reader = m_list[m_index]->createReader();
+ m_mutex.unlock();
+ return reader;
+ }
+ else
+ AUD_THROW(FileException, "The sound list is empty");
+}
+
+void SoundList::addSound(std::shared_ptr<ISound> sound)
+{
+ m_list.push_back(sound);
+}
+
+void SoundList::setRandomMode(bool random)
+{
+ m_random = random;
+}
+
+bool SoundList::getRandomMode()
+{
+ return m_random;
+}
+
+int SoundList::getSize()
+{
+ return m_list.size();
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Source.cpp b/extern/audaspace/src/fx/Source.cpp
new file mode 100644
index 00000000000..354ed69674b
--- /dev/null
+++ b/extern/audaspace/src/fx/Source.cpp
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/Source.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+Source::Source(float azimuth, float elevation, float distance) :
+ m_elevation(elevation), m_distance(distance)
+{
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+ m_azimuth = azimuth;
+}
+
+float Source::getAzimuth()
+{
+ return m_azimuth;
+}
+
+float Source::getElevation()
+{
+ return m_elevation;
+}
+
+float Source::getDistance()
+{
+ return m_distance;
+}
+
+float Source::getVolume()
+{
+ float volume = 1.0f - m_distance;
+ if(volume < 0.0f)
+ volume = 0.0f;
+ return volume;
+}
+
+void Source::setAzimuth(float azimuth)
+{
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+ m_azimuth = azimuth;
+}
+
+void Source::setElevation(float elevation)
+{
+ m_elevation = elevation;
+}
+
+void Source::setDistance(float distance)
+{
+ m_distance = distance;
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Sum.cpp b/extern/audaspace/src/fx/Sum.cpp
new file mode 100644
index 00000000000..306bc5de953
--- /dev/null
+++ b/extern/audaspace/src/fx/Sum.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Sum.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sum::Sum(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> Sum::createReader()
+{
+ std::vector<float> a, b;
+ a.push_back(1);
+ a.push_back(-1);
+ b.push_back(1);
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), b, a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Threshold.cpp b/extern/audaspace/src/fx/Threshold.cpp
new file mode 100644
index 00000000000..03c4ae4c8a5
--- /dev/null
+++ b/extern/audaspace/src/fx/Threshold.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Threshold.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+sample_t Threshold::thresholdFilter(CallbackIIRFilterReader* reader, float* threshold)
+{
+ float in = reader->x(0);
+ if(in >= *threshold)
+ return 1;
+ else if(in <= -*threshold)
+ return -1;
+ else
+ return 0;
+}
+
+void Threshold::endThresholdFilter(float* threshold)
+{
+ delete threshold;
+}
+
+Threshold::Threshold(std::shared_ptr<ISound> sound, float threshold) :
+ Effect(sound),
+ m_threshold(threshold)
+{
+}
+
+float Threshold::getThreshold() const
+{
+ return m_threshold;
+}
+
+std::shared_ptr<IReader> Threshold::createReader()
+{
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(getReader(), 1, 0, doFilterIIR(thresholdFilter), endFilterIIR(endThresholdFilter), new float(m_threshold)));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Volume.cpp b/extern/audaspace/src/fx/Volume.cpp
new file mode 100644
index 00000000000..231f5856a6c
--- /dev/null
+++ b/extern/audaspace/src/fx/Volume.cpp
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "fx/Volume.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Volume::Volume(std::shared_ptr<ISound> sound, float volume) :
+ Effect(sound),
+ m_volume(volume)
+{
+}
+
+float Volume::getVolume() const
+{
+ return m_volume;
+}
+
+std::shared_ptr<IReader> Volume::createReader()
+{
+ std::vector<float> a, b;
+ a.push_back(1);
+ b.push_back(m_volume);
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), b, a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/VolumeReader.cpp b/extern/audaspace/src/fx/VolumeReader.cpp
new file mode 100644
index 00000000000..ac1d4882a87
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeReader.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/VolumeReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+VolumeReader::VolumeReader(std::shared_ptr<IReader> reader, std::shared_ptr<VolumeStorage> volumeStorage) :
+ m_reader(reader), m_volumeStorage(volumeStorage)
+{
+}
+
+bool VolumeReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void VolumeReader::seek(int position)
+{
+ m_reader->seek(position);
+}
+
+int VolumeReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int VolumeReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs VolumeReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void VolumeReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+ for(int i = 0; i < length * m_reader->getSpecs().channels; i++)
+ buffer[i] = buffer[i] * m_volumeStorage->getVolume();
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/VolumeSound.cpp b/extern/audaspace/src/fx/VolumeSound.cpp
new file mode 100644
index 00000000000..b7f96225682
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeSound.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/VolumeSound.h"
+#include "fx/VolumeReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+VolumeSound::VolumeSound(std::shared_ptr<ISound> sound, std::shared_ptr<VolumeStorage> volumeStorage) :
+ m_sound(sound), m_volumeStorage(volumeStorage)
+{
+}
+
+std::shared_ptr<IReader> VolumeSound::createReader()
+{
+ return std::make_shared<VolumeReader>(m_sound->createReader(), m_volumeStorage);
+}
+
+std::shared_ptr<VolumeStorage> VolumeSound::getSharedVolume()
+{
+ return m_volumeStorage;
+}
+
+void VolumeSound::setSharedVolume(std::shared_ptr<VolumeStorage> volumeStorage)
+{
+ m_volumeStorage = volumeStorage;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/VolumeStorage.cpp b/extern/audaspace/src/fx/VolumeStorage.cpp
new file mode 100644
index 00000000000..4c5164d0ea1
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeStorage.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "fx/VolumeStorage.h"
+
+AUD_NAMESPACE_BEGIN
+VolumeStorage::VolumeStorage() :
+ m_volume(1.0f)
+{
+}
+
+VolumeStorage::VolumeStorage(float volume) :
+ m_volume(volume)
+{
+}
+
+float VolumeStorage::getVolume()
+{
+ return m_volume;
+}
+
+void VolumeStorage::setVolume(float volume)
+{
+ m_volume = volume;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Sawtooth.cpp b/extern/audaspace/src/generator/Sawtooth.cpp
new file mode 100644
index 00000000000..f5acad44839
--- /dev/null
+++ b/extern/audaspace/src/generator/Sawtooth.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Sawtooth.h"
+#include "generator/SawtoothReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sawtooth::Sawtooth(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Sawtooth::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Sawtooth::createReader()
+{
+ return std::shared_ptr<IReader>(new SawtoothReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SawtoothReader.cpp b/extern/audaspace/src/generator/SawtoothReader.cpp
new file mode 100644
index 00000000000..3664b8d3b61
--- /dev/null
+++ b/extern/audaspace/src/generator/SawtoothReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/SawtoothReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SawtoothReader::SawtoothReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SawtoothReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SawtoothReader::isSeekable() const
+{
+ return true;
+}
+
+void SawtoothReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate + 1.0f, 2.0f) - 1.0f;
+}
+
+int SawtoothReader::getLength() const
+{
+ return -1;
+}
+
+int SawtoothReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SawtoothReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SawtoothReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 1.0f)
+ m_sample -= std::floor(m_sample) + 1.0f;
+
+ buffer[i] = m_sample;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Silence.cpp b/extern/audaspace/src/generator/Silence.cpp
new file mode 100644
index 00000000000..a173a1bc5f6
--- /dev/null
+++ b/extern/audaspace/src/generator/Silence.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Silence.h"
+#include "generator/SilenceReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Silence::Silence()
+{
+}
+
+std::shared_ptr<IReader> Silence::createReader()
+{
+ return std::shared_ptr<IReader>(new SilenceReader());
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SilenceReader.cpp b/extern/audaspace/src/generator/SilenceReader.cpp
new file mode 100644
index 00000000000..39358cc087a
--- /dev/null
+++ b/extern/audaspace/src/generator/SilenceReader.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/SilenceReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SilenceReader::SilenceReader() :
+ m_position(0)
+{
+}
+
+bool SilenceReader::isSeekable() const
+{
+ return true;
+}
+
+void SilenceReader::seek(int position)
+{
+ m_position = position;
+}
+
+int SilenceReader::getLength() const
+{
+ return -1;
+}
+
+int SilenceReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SilenceReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = RATE_48000;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SilenceReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ std::memset(buffer, 0, length * sizeof(sample_t));
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Sine.cpp b/extern/audaspace/src/generator/Sine.cpp
new file mode 100644
index 00000000000..b7cdc132df6
--- /dev/null
+++ b/extern/audaspace/src/generator/Sine.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Sine.h"
+#include "generator/SineReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sine::Sine(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Sine::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Sine::createReader()
+{
+ return std::shared_ptr<IReader>(new SineReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SineReader.cpp b/extern/audaspace/src/generator/SineReader.cpp
new file mode 100644
index 00000000000..49b7cc3114b
--- /dev/null
+++ b/extern/audaspace/src/generator/SineReader.cpp
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/SineReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SineReader::SineReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SineReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SineReader::isSeekable() const
+{
+ return true;
+}
+
+void SineReader::seek(int position)
+{
+ m_position = position;
+}
+
+int SineReader::getLength() const
+{
+ return -1;
+}
+
+int SineReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SineReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SineReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // fill with sine data
+ for(int i = 0; i < length; i++)
+ {
+ buffer[i] = std::sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Square.cpp b/extern/audaspace/src/generator/Square.cpp
new file mode 100644
index 00000000000..361c243c549
--- /dev/null
+++ b/extern/audaspace/src/generator/Square.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Square.h"
+#include "generator/SquareReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Square::Square(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Square::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Square::createReader()
+{
+ return std::shared_ptr<IReader>(new SquareReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SquareReader.cpp b/extern/audaspace/src/generator/SquareReader.cpp
new file mode 100644
index 00000000000..8f49b097487
--- /dev/null
+++ b/extern/audaspace/src/generator/SquareReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/SquareReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SquareReader::SquareReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SquareReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SquareReader::isSeekable() const
+{
+ return true;
+}
+
+void SquareReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate, 2.0f);
+}
+
+int SquareReader::getLength() const
+{
+ return -1;
+}
+
+int SquareReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SquareReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SquareReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 2.0f)
+ m_sample = std::fmod(m_sample, 2.0f);
+
+ buffer[i] = (m_sample < 1.0f) * 2.0f - 1.0f;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Triangle.cpp b/extern/audaspace/src/generator/Triangle.cpp
new file mode 100644
index 00000000000..ca8f1b63fb9
--- /dev/null
+++ b/extern/audaspace/src/generator/Triangle.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/Triangle.h"
+#include "generator/TriangleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Triangle::Triangle(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Triangle::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Triangle::createReader()
+{
+ return std::shared_ptr<IReader>(new TriangleReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/TriangleReader.cpp b/extern/audaspace/src/generator/TriangleReader.cpp
new file mode 100644
index 00000000000..c363d3850ca
--- /dev/null
+++ b/extern/audaspace/src/generator/TriangleReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "generator/TriangleReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+TriangleReader::TriangleReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0.5f),
+ m_sampleRate(sampleRate)
+{
+}
+
+void TriangleReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool TriangleReader::isSeekable() const
+{
+ return true;
+}
+
+void TriangleReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate + 1.5f, 2.0f) - 1.0f;
+}
+
+int TriangleReader::getLength() const
+{
+ return -1;
+}
+
+int TriangleReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs TriangleReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void TriangleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 1.0f)
+ m_sample -= std::floor(m_sample) + 1.0f;
+
+ buffer[i] = std::fabs(m_sample) * 2.0f - 1.0f;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in b/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in
new file mode 100644
index 00000000000..d08804bc2e7
--- /dev/null
+++ b/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "plugin/PluginManager.h"
+
+#include <dlfcn.h>
+#include <dirent.h>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, void*> PluginManager::m_plugins;
+
+void* PluginManager::openLibrary(const std::string& path)
+{
+ return dlopen(path.c_str(), RTLD_LAZY);
+}
+
+void *PluginManager::lookupLibrary(void *handle, const std::string &name)
+{
+ return dlsym(handle, name.c_str());
+}
+
+void PluginManager::closeLibrary(void *handle)
+{
+ dlclose(handle);
+}
+
+bool PluginManager::loadPlugin(const std::string& path)
+{
+ void* handle = openLibrary(path);
+
+ if (!handle)
+ return false;
+
+ void (*registerPlugin)() = (void (*)())lookupLibrary(handle, "registerPlugin");
+ const char* (*getName)() = (const char* (*)())lookupLibrary(handle, "getName");
+
+ if(!registerPlugin || !getName)
+ {
+ closeLibrary(handle);
+ return false;
+ }
+
+ registerPlugin();
+
+ m_plugins[getName()] = handle;
+
+ return true;
+}
+
+#define STATIC_PLUGIN_CLASS(name) class name { public: static void registerPlugin(); };
+#define STATIC_PLUGIN_REGISTER(name) name::registerPlugin();
+
+@STATIC_PLUGIN_CLASSES@
+
+void PluginManager::loadPlugins(const std::string& path)
+{
+@STATIC_PLUGIN_REGISTERS@
+
+ std::string readpath = path;
+
+ if(path == "")
+ readpath = "@DEFAULT_PLUGIN_PATH@";
+
+ DIR* dir = opendir(readpath.c_str());
+
+ if(!dir)
+ return;
+
+ while(dirent* entry = readdir(dir))
+ {
+ const std::string filename = entry->d_name;
+ const std::string end = ".so";
+
+ if(filename.length() >= end.length() && filename.substr(filename.length() - end.length()) == end)
+ {
+ if(!loadPlugin(readpath + "/" + filename + ".@AUDASPACE_VERSION@"))
+ loadPlugin(readpath + "/" + filename);
+ }
+ }
+
+ closedir(dir);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in b/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in
new file mode 100644
index 00000000000..62350fd24fd
--- /dev/null
+++ b/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "plugin/PluginManager.h"
+
+#include <windows.h>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, void*> PluginManager::m_plugins;
+
+void* PluginManager::openLibrary(const std::string& path)
+{
+ return reinterpret_cast<void*>(LoadLibrary(path.c_str()));
+}
+
+void *PluginManager::lookupLibrary(void *handle, const std::string &name)
+{
+ return GetProcAddress(reinterpret_cast<HMODULE>(handle), name.c_str());
+}
+
+void PluginManager::closeLibrary(void *handle)
+{
+ FreeLibrary(reinterpret_cast<HMODULE>(handle));
+}
+
+bool PluginManager::loadPlugin(const std::string& path)
+{
+ void* handle = openLibrary(path);
+
+ if (!handle)
+ return false;
+
+ void (*registerPlugin)() = (void (*)())lookupLibrary(handle, "registerPlugin");
+ const char* (*getName)() = (const char* (*)())lookupLibrary(handle, "getName");
+
+ if(!registerPlugin || !getName)
+ {
+ closeLibrary(handle);
+ return false;
+ }
+
+ registerPlugin();
+
+ m_plugins[getName()] = handle;
+
+ return true;
+}
+
+#define STATIC_PLUGIN_CLASS(name) class name { public: static void registerPlugin(); };
+#define STATIC_PLUGIN_REGISTER(name) name::registerPlugin();
+
+@STATIC_PLUGIN_CLASSES@
+
+void PluginManager::loadPlugins(const std::string& path)
+{
+@STATIC_PLUGIN_REGISTERS@
+
+ std::string readpath = path;
+
+ if(path == "")
+ readpath = "@DEFAULT_PLUGIN_PATH@";
+
+ WIN32_FIND_DATA entry;
+ bool found_file = true;
+ std::string search = readpath + "\\*";
+ HANDLE dir = FindFirstFile(search.c_str(), &entry);
+
+ if(dir == INVALID_HANDLE_VALUE)
+ return;
+
+ while(found_file)
+ {
+ const std::string filename = entry.cFileName;
+ const std::string end = ".dll";
+
+ if(filename.length() >= end.length() && filename.substr(filename.length() - end.length()) == end)
+ {
+ loadPlugin(readpath + "/" + filename);
+ }
+
+ found_file = FindNextFile(dir, &entry);
+ }
+
+ FindClose(dir);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ChannelMapper.cpp b/extern/audaspace/src/respec/ChannelMapper.cpp
new file mode 100644
index 00000000000..e6e214598cb
--- /dev/null
+++ b/extern/audaspace/src/respec/ChannelMapper.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ChannelMapper::ChannelMapper(std::shared_ptr<ISound> sound, DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> ChannelMapper::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+ return std::shared_ptr<IReader>(new ChannelMapperReader(reader, m_specs.channels));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ChannelMapperReader.cpp b/extern/audaspace/src/respec/ChannelMapperReader.cpp
new file mode 100644
index 00000000000..850e54b73cf
--- /dev/null
+++ b/extern/audaspace/src/respec/ChannelMapperReader.cpp
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/ChannelMapperReader.h"
+
+#include <cmath>
+#include <limits>
+
+AUD_NAMESPACE_BEGIN
+
+ChannelMapperReader::ChannelMapperReader(std::shared_ptr<IReader> reader,
+ Channels channels) :
+ EffectReader(reader), m_target_channels(channels),
+ m_source_channels(CHANNELS_INVALID), m_mapping(nullptr), m_map_size(0), m_mono_angle(0)
+{
+}
+
+ChannelMapperReader::~ChannelMapperReader()
+{
+ delete[] m_mapping;
+}
+
+Channels ChannelMapperReader::getSourceChannels() const
+{
+ return m_reader->getSpecs().channels;
+}
+
+Channels ChannelMapperReader::getChannels() const
+{
+ return m_target_channels;
+}
+
+void ChannelMapperReader::setChannels(Channels channels)
+{
+ m_target_channels = channels;
+ calculateMapping();
+}
+
+float ChannelMapperReader::getMapping(int source, int target)
+{
+ Channels source_channels = m_reader->getSpecs().channels;
+ if(source_channels != m_source_channels)
+ {
+ m_source_channels = source_channels;
+ calculateMapping();
+ }
+
+ if(source < 0 || source >= source_channels || target < 0 || target >= m_target_channels)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_mapping[target * source_channels + source];
+}
+
+void ChannelMapperReader::setMonoAngle(float angle)
+{
+ if(angle != angle)
+ angle = 0;
+ m_mono_angle = angle;
+ if(m_source_channels == CHANNELS_MONO)
+ calculateMapping();
+}
+
+float ChannelMapperReader::angleDistance(float alpha, float beta)
+{
+ alpha = beta - alpha;
+
+ if(alpha > M_PI)
+ alpha -= 2 * M_PI;
+ if(alpha < -M_PI)
+ alpha += 2 * M_PI;
+
+ return alpha;
+}
+
+void ChannelMapperReader::calculateMapping()
+{
+ if(m_map_size < m_source_channels * m_target_channels)
+ {
+ delete[] m_mapping;
+ m_mapping = new float[m_source_channels * m_target_channels];
+ m_map_size = m_source_channels * m_target_channels;
+ }
+
+ for(int i = 0; i < m_source_channels * m_target_channels; i++)
+ m_mapping[i] = 0;
+
+ const Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
+ const Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
+
+ int lfe = -1;
+
+ for(int i = 0; i < m_target_channels; i++)
+ {
+ if(target_channels[i] == CHANNEL_LFE)
+ {
+ lfe = i;
+ break;
+ }
+ }
+
+ const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
+ const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
+
+ if(m_source_channels == CHANNELS_MONO)
+ source_angles = &m_mono_angle;
+
+ int channel_left, channel_right;
+ float angle_left, angle_right, angle;
+
+ for(int i = 0; i < m_source_channels; i++)
+ {
+ if(source_channels[i] == CHANNEL_LFE)
+ {
+ if(lfe != -1)
+ m_mapping[lfe * m_source_channels + i] = 1;
+
+ continue;
+ }
+
+ channel_left = channel_right = -1;
+ angle_left = -2 * M_PI;
+ angle_right = 2 * M_PI;
+
+ for(int j = 0; j < m_target_channels; j++)
+ {
+ if(j == lfe)
+ continue;
+ angle = angleDistance(source_angles[i], target_angles[j]);
+ if(angle < 0)
+ {
+ if(angle > angle_left)
+ {
+ angle_left = angle;
+ channel_left = j;
+ }
+ }
+ else
+ {
+ if(angle < angle_right)
+ {
+ angle_right = angle;
+ channel_right = j;
+ }
+ }
+ }
+
+ angle = angle_right - angle_left;
+ if(channel_right == -1 || angle == 0)
+ {
+ m_mapping[channel_left * m_source_channels + i] = 1;
+ }
+ else if(channel_left == -1)
+ {
+ m_mapping[channel_right * m_source_channels + i] = 1;
+ }
+ else
+ {
+ m_mapping[channel_left * m_source_channels + i] = std::cos(M_PI_2 * angle_left / angle);
+ m_mapping[channel_right * m_source_channels + i] = std::cos(M_PI_2 * angle_right / angle);
+ }
+ }
+}
+
+Specs ChannelMapperReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.channels = m_target_channels;
+ return specs;
+}
+
+void ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Channels channels = m_reader->getSpecs().channels;
+ if(channels != m_source_channels)
+ {
+ m_source_channels = channels;
+ calculateMapping();
+ }
+
+ if(m_source_channels == m_target_channels)
+ {
+ m_reader->read(length, eos, buffer);
+ return;
+ }
+
+ m_buffer.assureSize(length * channels * sizeof(sample_t));
+
+ sample_t* in = m_buffer.getBuffer();
+
+ m_reader->read(length, eos, in);
+
+ sample_t sum;
+
+ for(int i = 0; i < length; i++)
+ {
+ for(int j = 0; j < m_target_channels; j++)
+ {
+ sum = 0;
+ for(int k = 0; k < m_source_channels; k++)
+ sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
+ buffer[i * m_target_channels + j] = sum;
+ }
+ }
+}
+
+const Channel ChannelMapperReader::MONO_MAP[] =
+{
+ CHANNEL_FRONT_CENTER
+};
+
+const Channel ChannelMapperReader::STEREO_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT
+};
+
+const Channel ChannelMapperReader::STEREO_LFE_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_LFE
+};
+
+const Channel ChannelMapperReader::SURROUND4_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND5_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND51_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND61_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_CENTER,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND71_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT,
+ CHANNEL_SIDE_LEFT,
+ CHANNEL_SIDE_RIGHT
+};
+
+const Channel* ChannelMapperReader::CHANNEL_MAPS[] =
+{
+ ChannelMapperReader::MONO_MAP,
+ ChannelMapperReader::STEREO_MAP,
+ ChannelMapperReader::STEREO_LFE_MAP,
+ ChannelMapperReader::SURROUND4_MAP,
+ ChannelMapperReader::SURROUND5_MAP,
+ ChannelMapperReader::SURROUND51_MAP,
+ ChannelMapperReader::SURROUND61_MAP,
+ ChannelMapperReader::SURROUND71_MAP
+};
+
+const float ChannelMapperReader::MONO_ANGLES[] =
+{
+ 0.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::STEREO_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::STEREO_LFE_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND4_ANGLES[] =
+{
+ -45.0f * M_PI / 180.0f,
+ 45.0f * M_PI / 180.0f,
+ -135.0f * M_PI / 180.0f,
+ 135.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND5_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND51_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND61_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 180.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND71_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f,
+ -150.0f * M_PI / 180.0f,
+ 150.0f * M_PI / 180.0f
+};
+
+const float* ChannelMapperReader::CHANNEL_ANGLES[] =
+{
+ ChannelMapperReader::MONO_ANGLES,
+ ChannelMapperReader::STEREO_ANGLES,
+ ChannelMapperReader::STEREO_LFE_ANGLES,
+ ChannelMapperReader::SURROUND4_ANGLES,
+ ChannelMapperReader::SURROUND5_ANGLES,
+ ChannelMapperReader::SURROUND51_ANGLES,
+ ChannelMapperReader::SURROUND61_ANGLES,
+ ChannelMapperReader::SURROUND71_ANGLES
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/Converter.cpp b/extern/audaspace/src/respec/Converter.cpp
new file mode 100644
index 00000000000..f3cca20c741
--- /dev/null
+++ b/extern/audaspace/src/respec/Converter.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/Converter.h"
+#include "respec/ConverterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Converter::Converter(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> Converter::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+
+ if(m_specs.format != FORMAT_FLOAT32)
+ reader = std::shared_ptr<IReader>(new ConverterReader(reader, m_specs));
+
+ return reader;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ConverterFunctions.cpp b/extern/audaspace/src/respec/ConverterFunctions.cpp
new file mode 100644
index 00000000000..d3df4a9ecbb
--- /dev/null
+++ b/extern/audaspace/src/respec/ConverterFunctions.cpp
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/ConverterFunctions.h"
+
+#include <stdint.h>
+
+#define U8_0 0x80
+#define S16_MAX ((int16_t)0x7FFF)
+#define S16_MIN ((int16_t)0x8000)
+#define S16_FLT 32767.0f
+#define S32_MAX ((int32_t)0x7FFFFFFF)
+#define S32_MIN ((int32_t)0x80000000)
+#define S32_FLT 2147483647.0f
+#define FLT_MAX 1.0f
+#define FLT_MIN -1.0f
+
+AUD_NAMESPACE_BEGIN
+
+void convert_u8_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int16_t)source[i]) - U8_0) << 8;
+}
+
+void convert_u8_s24_be(data_t* target, data_t* source, int length)
+{
+ for(int i = length - 1; i >= 0; i--)
+ {
+ target[i*3] = source[i] - U8_0;
+ target[i*3+1] = 0;
+ target[i*3+2] = 0;
+ }
+}
+
+void convert_u8_s24_le(data_t* target, data_t* source, int length)
+{
+ for(int i = length - 1; i >= 0; i--)
+ {
+ target[i*3+2] = source[i] - U8_0;
+ target[i*3+1] = 0;
+ target[i*3] = 0;
+ }
+}
+
+void convert_u8_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) << 24;
+}
+
+void convert_u8_float(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) / ((float)U8_0);
+}
+
+void convert_u8_double(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) / ((double)U8_0);
+}
+
+void convert_s16_u8(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ target[i] = (unsigned char)((s[i] >> 8) + U8_0);
+}
+
+void convert_s16_s24_be(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ t = s[i];
+ target[i*3] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
+ target[i*3+2] = 0;
+ }
+}
+
+void convert_s16_s24_le(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ t = s[i];
+ target[i*3+2] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
+ target[i*3] = 0;
+ }
+}
+
+void convert_s16_s32(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = ((int32_t)s[i]) << 16;
+}
+
+void convert_s16_float(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ float* t = (float*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S16_FLT;
+}
+
+void convert_s16_double(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S16_FLT;
+}
+
+void convert_s24_u8_be(data_t* target, data_t* source, int length)
+{
+ for(int i = 0; i < length; i++)
+ target[i] = source[i*3] ^ U8_0;
+}
+
+void convert_s24_u8_le(data_t* target, data_t* source, int length)
+{
+ for(int i = 0; i < length; i++)
+ target[i] = source[i*3+2] ^ U8_0;
+}
+
+void convert_s24_s16_be(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3] << 8 | source[i*3+1];
+}
+
+void convert_s24_s16_le(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3+2] << 8 | source[i*3+1];
+}
+
+void convert_s24_s24(data_t* target, data_t* source, int length)
+{
+ std::memcpy(target, source, length * 3);
+}
+
+void convert_s24_s32_be(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+}
+
+void convert_s24_s32_le(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+}
+
+void convert_s24_float_be(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_float_le(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_double_be(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_double_le(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s32_u8(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ target[i] = (unsigned char)((s[i] >> 24) + U8_0);
+}
+
+void convert_s32_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ int32_t* s = (int32_t*) source;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] >> 16;
+}
+
+void convert_s32_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ int32_t t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i];
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_s32_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ int32_t t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i];
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_s32_float(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] / S32_FLT;
+}
+
+void convert_s32_double(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S32_FLT;
+}
+
+void convert_float_u8(data_t* target, data_t* source, int length)
+{
+ float* s = (float*) source;
+ float t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i] + FLT_MAX;
+ if(t <= 0.0f)
+ target[i] = 0;
+ else if(t >= 2.0f)
+ target[i] = 255;
+ else
+ target[i] = (unsigned char)(t*127);
+ }
+}
+
+void convert_float_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S16_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S16_MAX;
+ else
+ t[i] = (int16_t)(s[i] * S16_MAX);
+ }
+}
+
+void convert_float_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_float_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_float_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S32_MAX;
+ else
+ t[i] = (int32_t)(s[i]*S32_MAX);
+ }
+}
+
+void convert_float_double(data_t* target, data_t* source, int length)
+{
+ float* s = (float*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i];
+}
+
+void convert_double_u8(data_t* target, data_t* source, int length)
+{
+ double* s = (double*) source;
+ double t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i] + FLT_MAX;
+ if(t <= 0.0)
+ target[i] = 0;
+ else if(t >= 2.0)
+ target[i] = 255;
+ else
+ target[i] = (unsigned char)(t*127);
+ }
+}
+
+void convert_double_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S16_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S16_MAX;
+ else
+ t[i] = (int16_t)(s[i]*S16_MAX);
+ }
+}
+
+void convert_double_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_double_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_double_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S32_MAX;
+ else
+ t[i] = (int32_t)(s[i]*S32_MAX);
+ }
+}
+
+void convert_double_float(data_t* target, data_t* source, int length)
+{
+ double* s = (double*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i];
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ConverterReader.cpp b/extern/audaspace/src/respec/ConverterReader.cpp
new file mode 100644
index 00000000000..88a5e7f225d
--- /dev/null
+++ b/extern/audaspace/src/respec/ConverterReader.cpp
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/ConverterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ConverterReader::ConverterReader(std::shared_ptr<IReader> reader,
+ DeviceSpecs specs) :
+ EffectReader(reader),
+ m_format(specs.format)
+{
+ switch(m_format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ break;
+ case FORMAT_S24:
+#ifdef __BIG_ENDIAN__
+ m_convert = convert_float_s24_be;
+#else
+ m_convert = convert_float_s24_le;
+#endif
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ break;
+ case FORMAT_FLOAT32:
+ m_convert = convert_copy<float>;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ break;
+ default:
+ break;
+ }
+}
+
+void ConverterReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer.assureSize(length * samplesize);
+
+ m_reader->read(length, eos, m_buffer.getBuffer());
+
+ m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(),
+ length * specs.channels);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/JOSResample.cpp b/extern/audaspace/src/respec/JOSResample.cpp
new file mode 100644
index 00000000000..fae116d057a
--- /dev/null
+++ b/extern/audaspace/src/respec/JOSResample.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+JOSResample::JOSResample(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> JOSResample::createReader()
+{
+ return std::shared_ptr<IReader>(new JOSResampleReader(getReader(), m_specs.rate));
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.cpp b/extern/audaspace/src/respec/JOSResampleReader.cpp
index 0448c75d777..6753a2e8b6b 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReader.cpp
+++ b/extern/audaspace/src/respec/JOSResampleReader.cpp
@@ -1,68 +1,26 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_JOSResampleReader.cpp
- * \ingroup audaspaceintern
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-#include "AUD_JOSResampleReader.h"
-
-#include "AUD_JOSResampleReaderCoeff.cpp"
+#include "respec/JOSResampleReader.h"
+#include <algorithm>
#include <cmath>
#include <cstring>
-#include <iostream>
-
-/* MSVC does not have lrint */
-#ifdef _MSC_VER
-#if _MSC_VER < 1800
-#ifdef _M_X64
-#include <emmintrin.h>
-static inline int lrint(double d)
-{
- return _mm_cvtsd_si32(_mm_load_sd(&d));
-}
-#else
-static inline int lrint(double d)
-{
- int i;
-
- _asm{
- fld d
- fistp i
- };
-
- return i;
-}
-#endif
-#endif
-#endif
-// UNUSED
-// #define CC m_channels + channel
-
-#define AUD_RATE_MAX 256
+#define RATE_MAX 256
#define SHIFT_BITS 12
#define double_to_fp(x) (lrint(x * double(1 << SHIFT_BITS)))
#define int_to_fp(x) (x << SHIFT_BITS)
@@ -71,9 +29,11 @@ static inline int lrint(double d)
#define fp_rest(x) (x & ((1 << SHIFT_BITS) - 1))
#define fp_rest_to_double(x) fp_to_double(fp_rest(x))
-AUD_JOSResampleReader::AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(AUD_CHANNELS_INVALID),
+AUD_NAMESPACE_BEGIN
+
+JOSResampleReader::JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ ResampleReader(reader, rate),
+ m_channels(CHANNELS_INVALID),
m_n(0),
m_P(0),
m_cache_valid(0),
@@ -81,7 +41,7 @@ AUD_JOSResampleReader::AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> read
{
}
-void AUD_JOSResampleReader::reset()
+void JOSResampleReader::reset()
{
m_cache_valid = 0;
m_n = 0;
@@ -89,25 +49,25 @@ void AUD_JOSResampleReader::reset()
m_last_factor = 0;
}
-void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize)
+void JOSResampleReader::updateBuffer(int size, double factor, int samplesize)
{
unsigned int len;
double num_samples = double(m_len) / double(m_L);
// first calculate what length we need right now
if(factor >= 1)
- len = ceil(num_samples);
+ len = std::ceil(num_samples);
else
- len = (unsigned int)(ceil(num_samples / factor));
+ len = (unsigned int)(std::ceil(num_samples / factor));
// then check if afterwards the length is enough for the maximum rate
- if(len + size < num_samples * AUD_RATE_MAX)
- len = num_samples * AUD_RATE_MAX - size;
+ if(len + size < num_samples * RATE_MAX)
+ len = num_samples * RATE_MAX - size;
if(m_n > len)
{
sample_t* buf = m_buffer.getBuffer();
len = m_n - len;
- memmove(buf, buf + len * m_channels, (m_cache_valid - len) * samplesize);
+ std::memmove(buf, buf + len * m_channels, (m_cache_valid - len) * samplesize);
m_n -= len;
m_cache_valid -= len;
}
@@ -115,7 +75,7 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
m_buffer.assureSize((m_cache_valid + size) * samplesize, true);
}
-#define RESAMPLE_METHOD(name, left, right) void AUD_JOSResampleReader::name(double target_factor, int length, sample_t* buffer)\
+#define RESAMPLE_METHOD(name, left, right) void JOSResampleReader::name(double target_factor, int length, sample_t* buffer)\
{\
sample_t* buf = m_buffer.getBuffer();\
\
@@ -134,13 +94,13 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
{\
factor = (m_last_factor * (length - t - 1) + target_factor * (t + 1)) / length;\
\
- memset(sums, 0, sizeof(double) * m_channels);\
+ std::memset(sums, 0, sizeof(double) * m_channels);\
\
if(factor >= 1)\
{\
P = double_to_fp(m_P * m_L);\
\
- end = floor(m_len / double(m_L) - m_P) - 1;\
+ end = std::floor(m_len / double(m_L) - m_P) - 1;\
if(m_n < end)\
end = m_n;\
\
@@ -158,7 +118,7 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
\
P = int_to_fp(m_L) - P;\
\
- end = floor((m_len - 1) / double(m_L) + m_P) - 1;\
+ end = std::floor((m_len - 1) / double(m_L) + m_P) - 1;\
if(m_cache_valid - m_n - 2 < end)\
end = m_cache_valid - m_n - 2;\
\
@@ -224,13 +184,13 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
\
for(channel = 0; channel < m_channels; channel++)\
{\
- *buffer = factor * sums[channel];\
+ *buffer = factor * sums[channel];\
buffer++;\
}\
}\
\
- m_P += fmod(1.0 / factor, 1.0);\
- m_n += floor(1.0 / factor);\
+ m_P += std::fmod(1.0 / factor, 1.0);\
+ m_n += std::floor(1.0 / factor);\
\
while(m_P >= 1.0)\
{\
@@ -278,37 +238,36 @@ RESAMPLE_METHOD(resample_stereo, {
sums[1] += data[2] * v;
})
-void AUD_JOSResampleReader::seek(int position)
+void JOSResampleReader::seek(int position)
{
- position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+ position = std::floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
m_reader->seek(position);
reset();
}
-int AUD_JOSResampleReader::getLength() const
+int JOSResampleReader::getLength() const
{
- return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
+ return std::floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
}
-int AUD_JOSResampleReader::getPosition() const
+int JOSResampleReader::getPosition() const
{
- return floor((m_reader->getPosition() + double(m_P))
- * m_rate / m_reader->getSpecs().rate);
+ return std::floor((m_reader->getPosition() + double(m_P)) * m_rate / m_reader->getSpecs().rate);
}
-AUD_Specs AUD_JOSResampleReader::getSpecs() const
+Specs JOSResampleReader::getSpecs() const
{
- AUD_Specs specs = m_reader->getSpecs();
+ Specs specs = m_reader->getSpecs();
specs.rate = m_rate;
return specs;
}
-void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
+void JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
{
if(length == 0)
return;
- AUD_Specs specs = m_reader->getSpecs();
+ Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
double target_factor = double(m_rate) / double(specs.rate);
@@ -324,14 +283,14 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
switch(m_channels)
{
- case AUD_CHANNELS_MONO:
- m_resample = &AUD_JOSResampleReader::resample_mono;
+ case CHANNELS_MONO:
+ m_resample = &JOSResampleReader::resample_mono;
break;
- case AUD_CHANNELS_STEREO:
- m_resample = &AUD_JOSResampleReader::resample_stereo;
+ case CHANNELS_STEREO:
+ m_resample = &JOSResampleReader::resample_stereo;
break;
default:
- m_resample = &AUD_JOSResampleReader::resample;
+ m_resample = &JOSResampleReader::resample;
break;
}
}
@@ -355,7 +314,7 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
if(length > 0)
{
- memcpy(buffer, buf + m_n * m_channels, length * samplesize);
+ std::memcpy(buffer, buf + m_n * m_channels, length * samplesize);
m_n += length;
}
@@ -363,12 +322,12 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
}
// use minimum for the following calculations
- double factor = AUD_MIN(target_factor, m_last_factor);
+ double factor = std::min(target_factor, m_last_factor);
if(factor >= 1)
- len = (int(m_n) - m_cache_valid) + int(ceil(length / factor)) + ceil(num_samples);
+ len = (int(m_n) - m_cache_valid) + int(std::ceil(length / factor)) + std::ceil(num_samples);
else
- len = (int(m_n) - m_cache_valid) + int(ceil(length / factor) + ceil(num_samples / factor));
+ len = (int(m_n) - m_cache_valid) + int(std::ceil(length / factor) + std::ceil(num_samples / factor));
if(len > 0)
{
@@ -386,22 +345,22 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
else
{
// use maximum for the following calculations
- factor = AUD_MAX(target_factor, m_last_factor);
+ factor = std::max(target_factor, m_last_factor);
if(eos)
{
// end of stream, let's check how many more samples we can produce
- len = floor((m_cache_valid - m_n) * factor);
+ len = std::floor((m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
else
{
- // not enough data available yet, so we recalculate how many samples we can calculate
+ // not enough data available yet, so we recalculate how many samples we can calculate
if(factor >= 1)
- len = floor((num_samples + m_cache_valid - m_n) * factor);
+ len = std::floor((num_samples + m_cache_valid - m_n) * factor);
else
- len = floor((num_samples * factor + m_cache_valid - m_n) * factor);
+ len = std::floor((num_samples * factor + m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
@@ -420,3 +379,5 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
eos = eos && ((m_n == m_cache_valid) || (length == 0));
}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp b/extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp
index f8fefd5b88f..133e081f4a7 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
+++ b/extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp
@@ -1,39 +1,29 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
- * \ingroup audaspaceintern
- */
-
-#include "AUD_JOSResampleReader.h"
+#include "respec/JOSResampleReader.h"
// sinc filter coefficients, Nz = 136, L = 2304, freq = 0.963904, Kaiser Window B = 16
-const int AUD_JOSResampleReader::m_len = 325078;
-const int AUD_JOSResampleReader::m_L = 2304;
+AUD_NAMESPACE_BEGIN
+
+const int JOSResampleReader::m_len = 325078;
+const int JOSResampleReader::m_L = 2304;
-const float AUD_JOSResampleReader::m_coeff[] = {
+const float JOSResampleReader::m_coeff[] = {
9.639035268e-01f, 9.639032492e-01f, 9.639024165e-01f, 9.639010286e-01f, 9.638990855e-01f, 9.638965872e-01f, 9.638935338e-01f, 9.638899253e-01f, 9.638857615e-01f, 9.638810427e-01f,
9.638757686e-01f, 9.638699395e-01f, 9.638635552e-01f, 9.638566158e-01f, 9.638491212e-01f, 9.638410716e-01f, 9.638324668e-01f, 9.638233070e-01f, 9.638135921e-01f, 9.638033220e-01f,
9.637924970e-01f, 9.637811168e-01f, 9.637691817e-01f, 9.637566915e-01f, 9.637436463e-01f, 9.637300461e-01f, 9.637158908e-01f, 9.637011807e-01f, 9.636859155e-01f, 9.636700955e-01f,
@@ -32543,3 +32533,5 @@ const float AUD_JOSResampleReader::m_coeff[] = {
-6.072286860e-11f, -5.735986806e-11f, -5.399941461e-11f, -5.064151335e-11f, -4.728616936e-11f, -4.393338771e-11f, -4.058317348e-11f, -3.723553173e-11f, -3.389046751e-11f, -3.054798585e-11f,
-2.720809180e-11f, -2.387079037e-11f, -2.053608658e-11f, -1.720398544e-11f, -1.387449194e-11f, -1.054761107e-11f, -7.223347816e-12f, -3.901707142e-12f, -3.901707142e-12f
};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/LinearResample.cpp b/extern/audaspace/src/respec/LinearResample.cpp
new file mode 100644
index 00000000000..bcdc3409771
--- /dev/null
+++ b/extern/audaspace/src/respec/LinearResample.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/LinearResample.h"
+#include "respec/LinearResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+LinearResample::LinearResample(std::shared_ptr<ISound> sound, DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> LinearResample::createReader()
+{
+ return std::shared_ptr<IReader>(new LinearResampleReader(getReader(), m_specs.rate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/LinearResampleReader.cpp b/extern/audaspace/src/respec/LinearResampleReader.cpp
new file mode 100644
index 00000000000..53d506115ce
--- /dev/null
+++ b/extern/audaspace/src/respec/LinearResampleReader.cpp
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/LinearResampleReader.h"
+
+#include <cmath>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+LinearResampleReader::LinearResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ ResampleReader(reader, rate),
+ m_channels(reader->getSpecs().channels),
+ m_cache_pos(0),
+ m_cache_ok(false)
+{
+ Specs specs = { rate, m_channels };
+ m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
+}
+
+void LinearResampleReader::seek(int position)
+{
+ position = std::floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+ m_reader->seek(position);
+ m_cache_ok = false;
+ m_cache_pos = 0;
+}
+
+int LinearResampleReader::getLength() const
+{
+ return std::floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
+}
+
+int LinearResampleReader::getPosition() const
+{
+ return std::floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 1 : 0))
+ * m_rate / m_reader->getSpecs().rate);
+}
+
+Specs LinearResampleReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.rate = m_rate;
+ return specs;
+}
+
+void LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(length == 0)
+ return;
+
+ Specs specs = m_reader->getSpecs();
+
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+ int size = length;
+ float factor = m_rate / m_reader->getSpecs().rate;
+ float spos = 0.0f;
+ sample_t low, high;
+ eos = false;
+
+ // check for channels changed
+
+ if(specs.channels != m_channels)
+ {
+ m_cache.resize(2 * samplesize);
+ m_channels = specs.channels;
+ m_cache_ok = false;
+ }
+
+ if(factor == 1 && (!m_cache_ok || m_cache_pos == 1))
+ {
+ // can read directly!
+ m_reader->read(length, eos, buffer);
+
+ if(length > 0)
+ {
+ std::memcpy(m_cache.getBuffer() + m_channels, buffer + m_channels * (length - 1), samplesize);
+ m_cache_pos = 1;
+ m_cache_ok = true;
+ }
+
+ return;
+ }
+
+ int len;
+ sample_t* buf;
+
+ if(m_cache_ok)
+ {
+ int need = std::ceil(length / factor + m_cache_pos) - 1;
+
+ len = need;
+
+ m_buffer.assureSize((len + 2) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ std::memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
+ m_reader->read(len, eos, buf + 2 * m_channels);
+
+ if(len < need)
+ length = std::floor((len + 1 - m_cache_pos) * factor);
+ }
+ else
+ {
+ m_cache_pos = 1 - 1 / factor;
+
+ int need = std::ceil(length / factor + m_cache_pos);
+
+ len = need;
+
+ m_buffer.assureSize((len + 1) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ std::memset(buf, 0, samplesize);
+ m_reader->read(len, eos, buf + m_channels);
+
+ if(len == 0)
+ {
+ length = 0;
+ return;
+ }
+
+ if(len < need)
+ {
+ length = std::floor((len - m_cache_pos) * factor);
+ }
+
+ m_cache_ok = true;
+ }
+
+ if(length == 0)
+ return;
+
+ for(int channel = 0; channel < m_channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ spos = (i + 1) / factor + m_cache_pos;
+
+ low = buf[(int)std::floor(spos) * m_channels + channel];
+ high = buf[(int)std::ceil(spos) * m_channels + channel];
+
+ buffer[i * m_channels + channel] = low + (spos - std::floor(spos)) * (high - low);
+ }
+ }
+
+ if(std::floor(spos) == spos)
+ {
+ std::memcpy(m_cache.getBuffer() + m_channels, buf + int(std::floor(spos)) * m_channels, samplesize);
+ m_cache_pos = 1;
+ }
+ else
+ {
+ std::memcpy(m_cache.getBuffer(), buf + int(std::floor(spos)) * m_channels, 2 * samplesize);
+ m_cache_pos = spos - std::floor(spos);
+ }
+
+ eos &= length < size;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/Mixer.cpp b/extern/audaspace/src/respec/Mixer.cpp
new file mode 100644
index 00000000000..d63f0bab2bb
--- /dev/null
+++ b/extern/audaspace/src/respec/Mixer.cpp
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/Mixer.h"
+
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+Mixer::Mixer(DeviceSpecs specs) :
+ m_specs(specs)
+{
+ switch(m_specs.format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ break;
+ case FORMAT_S24:
+
+#ifdef __BIG_ENDIAN__
+ m_convert = convert_float_s24_be;
+#else
+ m_convert = convert_float_s24_le;
+#endif
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ break;
+ case FORMAT_FLOAT32:
+ m_convert = convert_copy<float>;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ break;
+ default:
+ break;
+ }
+}
+
+DeviceSpecs Mixer::getSpecs() const
+{
+ return m_specs;
+}
+
+void Mixer::setSpecs(Specs specs)
+{
+ m_specs.specs = specs;
+}
+
+void Mixer::clear(int length)
+{
+ m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
+
+ m_length = length;
+
+ std::memset(m_buffer.getBuffer(), 0, length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
+}
+
+void Mixer::mix(sample_t* buffer, int start, int length, float volume)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ length = (std::min(m_length, length + start) - start) * m_specs.channels;
+ start *= m_specs.channels;
+
+ for(int i = 0; i < length; i++)
+ out[i + start] += buffer[i] * volume;
+}
+
+void Mixer::mix(sample_t* buffer, int start, int length, float volume_to, float volume_from)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ length = (std::min(m_length, length + start) - start);
+
+ for(int i = 0; i < length; i++)
+ {
+ float volume = volume_from * (1.0f - i / float(length)) + volume_to * (i / float(length));
+
+ for(int c = 0; c < m_specs.channels; c++)
+ out[(i + start) * m_specs.channels + c] += buffer[i * m_specs.channels + c] * volume;
+ }
+}
+
+void Mixer::read(data_t* buffer, float volume)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ for(int i = 0; i < m_length * m_specs.channels; i++)
+ out[i] *= volume;
+
+ m_convert(buffer, (data_t*) out, m_length * m_specs.channels);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ResampleReader.cpp b/extern/audaspace/src/respec/ResampleReader.cpp
new file mode 100644
index 00000000000..d7f5bff3a51
--- /dev/null
+++ b/extern/audaspace/src/respec/ResampleReader.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/ResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ResampleReader::ResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ EffectReader(reader), m_rate(rate)
+{
+}
+
+void ResampleReader::setRate(SampleRate rate)
+{
+ m_rate = rate;
+}
+
+SampleRate ResampleReader::getRate()
+{
+ return m_rate;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/SpecsChanger.cpp b/extern/audaspace/src/respec/SpecsChanger.cpp
new file mode 100644
index 00000000000..146d9789160
--- /dev/null
+++ b/extern/audaspace/src/respec/SpecsChanger.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<IReader> SpecsChanger::getReader() const
+{
+ return m_sound->createReader();
+}
+
+SpecsChanger::SpecsChanger(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ m_specs(specs), m_sound(sound)
+{
+}
+
+DeviceSpecs SpecsChanger::getSpecs() const
+{
+ return m_specs;
+}
+
+std::shared_ptr<ISound> SpecsChanger::getSound() const
+{
+ return m_sound;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp
new file mode 100644
index 00000000000..306ba8e07f5
--- /dev/null
+++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/AnimateableProperty.h"
+
+#include <cstring>
+#include <cmath>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+AnimateableProperty::AnimateableProperty(int count) :
+ Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
+{
+ std::memset(getBuffer(), 0, count * sizeof(float));
+}
+
+AnimateableProperty::AnimateableProperty(int count, float value) :
+ Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
+{
+ sample_t* buf = getBuffer();
+
+ for(int i = 0; i < count; i++)
+ buf[i] = value;
+}
+
+void AnimateableProperty::updateUnknownCache(int start, int end)
+{
+ float* buf = getBuffer();
+
+ // we could do a better interpolation than zero order, but that doesn't work with Blender's animation system
+ // as frames are only written when changing, so to support jumps, we need zero order interpolation here.
+ for(int i = start; i <= end; i++)
+ std::memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
+}
+
+AnimateableProperty::~AnimateableProperty()
+{
+}
+
+int AnimateableProperty::getCount() const
+{
+ return m_count;
+}
+
+void AnimateableProperty::write(const float* data)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_isAnimated = false;
+ m_unknown.clear();
+ std::memcpy(getBuffer(), data, m_count * sizeof(float));
+}
+
+void AnimateableProperty::write(const float* data, int position, int count)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ int pos = getSize() / (sizeof(float) * m_count);
+
+ if(!m_isAnimated)
+ pos = 0;
+
+ m_isAnimated = true;
+
+ assureSize((count + position) * m_count * sizeof(float), true);
+
+ float* buf = getBuffer();
+
+ std::memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
+
+ // have to fill up space between?
+ if(pos < position)
+ {
+ m_unknown.push_back(Unknown(pos, position - 1));
+
+ // if the buffer was not animated before, we copy the previous static value
+ if(pos == 0)
+ pos = 1;
+
+ updateUnknownCache(pos, position - 1);
+ }
+ // otherwise it's not at the end, let's check if some unknown part got filled
+ else
+ {
+ bool erased = false;
+
+ for(auto it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++)
+ {
+ erased = false;
+
+ // unknown area before position
+ if(it->end < position)
+ continue;
+
+ // we're after the new area, let's stop
+ if(it->start >= position + count)
+ break;
+
+ // we have an intersection, now 4 cases:
+ // the start is included
+ if(position <= it->start)
+ {
+ // the end is included
+ if(position + count > it->end)
+ {
+ // simply delete
+ it = m_unknown.erase(it);
+ erased = true;
+ }
+ // the end is excluded, a second part remains
+ else
+ {
+ // update second part
+ it->start = position + count;
+ updateUnknownCache(it->start, it->end);
+ break;
+ }
+ }
+ // start is excluded, a first part remains
+ else
+ {
+ // the end is included
+ if(position + count > it->end)
+ {
+ // update first part
+ it->end = position - 1;
+ }
+ // the end is excluded, a second part remains
+ else
+ {
+ // add another item and update both parts
+ m_unknown.insert(it, Unknown(it->start, position - 1));
+ it->start = position + count;
+ updateUnknownCache(it->start, it->end);
+ }
+ }
+ }
+ }
+}
+
+void AnimateableProperty::read(float position, float* out)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(!m_isAnimated)
+ {
+ std::memcpy(out, getBuffer(), m_count * sizeof(float));
+ return;
+ }
+
+ int last = getSize() / (sizeof(float) * m_count) - 1;
+ float t = position - std::floor(position);
+
+ if(position >= last)
+ {
+ position = last;
+ t = 0;
+ }
+
+ if(t == 0)
+ {
+ std::memcpy(out, getBuffer() + int(std::floor(position)) * m_count, m_count * sizeof(float));
+ }
+ else
+ {
+ int pos = int(std::floor(position)) * m_count;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ float m0, m1;
+ float* p0;
+ float* p1 = getBuffer() + pos;
+ float* p2;
+ float* p3;
+ last *= m_count;
+
+ if(pos == 0)
+ p0 = p1;
+ else
+ p0 = p1 - m_count;
+
+ p2 = p1 + m_count;
+ if(pos + m_count == last)
+ p3 = p2;
+ else
+ p3 = p2 + m_count;
+
+ for(int i = 0; i < m_count; i++)
+ {
+ m0 = (p2[i] - p0[i]) / 2.0f;
+ m1 = (p3[i] - p1[i]) / 2.0f;
+
+ out[i] = (2 * t3 - 3 * t2 + 1) * p0[i] + (-2 * t3 + 3 * t2) * p1[i] +
+ (t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
+ }
+ }
+}
+
+bool AnimateableProperty::isAnimated() const
+{
+ return m_isAnimated;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Double.cpp b/extern/audaspace/src/sequence/Double.cpp
new file mode 100644
index 00000000000..1086be84a11
--- /dev/null
+++ b/extern/audaspace/src/sequence/Double.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/Double.h"
+#include "sequence/DoubleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Double::Double(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
+ m_sound1(sound1), m_sound2(sound2)
+{
+}
+
+std::shared_ptr<IReader> Double::createReader()
+{
+ std::shared_ptr<IReader> reader1 = m_sound1->createReader();
+ std::shared_ptr<IReader> reader2 = m_sound2->createReader();
+
+ return std::shared_ptr<IReader>(new DoubleReader(reader1, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/DoubleReader.cpp b/extern/audaspace/src/sequence/DoubleReader.cpp
new file mode 100644
index 00000000000..33ab34ce366
--- /dev/null
+++ b/extern/audaspace/src/sequence/DoubleReader.cpp
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/DoubleReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+DoubleReader::DoubleReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
+ m_reader1(reader1), m_reader2(reader2), m_finished1(false)
+{
+ Specs s1, s2;
+ s1 = reader1->getSpecs();
+ s2 = reader2->getSpecs();
+}
+
+DoubleReader::~DoubleReader()
+{
+}
+
+bool DoubleReader::isSeekable() const
+{
+ return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void 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 DoubleReader::getLength() const
+{
+ int len1 = m_reader1->getLength();
+ int len2 = m_reader2->getLength();
+ if(len1 < 0 || len2 < 0)
+ return -1;
+ return len1 + len2;
+}
+
+int DoubleReader::getPosition() const
+{
+ return m_reader1->getPosition() + m_reader2->getPosition();
+}
+
+Specs DoubleReader::getSpecs() const
+{
+ return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
+}
+
+void DoubleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ eos = false;
+
+ if(!m_finished1)
+ {
+ int len = length;
+
+ m_reader1->read(len, m_finished1, buffer);
+
+ if(len < length)
+ {
+ Specs specs1, specs2;
+ specs1 = m_reader1->getSpecs();
+ specs2 = m_reader2->getSpecs();
+ if(AUD_COMPARE_SPECS(specs1, specs2))
+ {
+ int len2 = length - len;
+ m_reader2->read(len2, eos, buffer + specs1.channels * len);
+ length = len + len2;
+ }
+ else
+ length = len;
+ }
+ }
+ else
+ {
+ m_reader2->read(length, eos, buffer);
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/PingPong.cpp b/extern/audaspace/src/sequence/PingPong.cpp
new file mode 100644
index 00000000000..19bfb10fc2d
--- /dev/null
+++ b/extern/audaspace/src/sequence/PingPong.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/PingPong.h"
+#include "sequence/DoubleReader.h"
+#include "fx/ReverseReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+PingPong::PingPong(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> PingPong::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+ std::shared_ptr<IReader> reader2 = std::shared_ptr<IReader>(new ReverseReader(getReader()));
+
+ return std::shared_ptr<IReader>(new DoubleReader(reader, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Sequence.cpp b/extern/audaspace/src/sequence/Sequence.cpp
new file mode 100644
index 00000000000..eaec4d84ae1
--- /dev/null
+++ b/extern/audaspace/src/sequence/Sequence.cpp
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/Sequence.h"
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceData.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sequence::Sequence(Specs specs, float fps, bool muted)
+{
+ m_sequence = std::shared_ptr<SequenceData>(new SequenceData(specs, fps, muted));
+}
+
+Specs Sequence::getSpecs()
+{
+ return m_sequence->getSpecs();
+}
+
+void Sequence::setSpecs(Specs specs)
+{
+ m_sequence->setSpecs(specs);
+}
+
+float Sequence::getFPS() const
+{
+ return m_sequence->getFPS();
+}
+
+void Sequence::setFPS(float fps)
+{
+ m_sequence->setFPS(fps);
+}
+
+void Sequence::mute(bool muted)
+{
+ m_sequence->mute(muted);
+}
+
+bool Sequence::isMuted() const
+{
+ return m_sequence->isMuted();
+}
+
+float Sequence::getSpeedOfSound() const
+{
+ return m_sequence->getSpeedOfSound();
+}
+
+void Sequence::setSpeedOfSound(float speed)
+{
+ m_sequence->setSpeedOfSound(speed);
+}
+
+float Sequence::getDopplerFactor() const
+{
+ return m_sequence->getDopplerFactor();
+}
+
+void Sequence::setDopplerFactor(float factor)
+{
+ m_sequence->setDopplerFactor(factor);
+}
+
+DistanceModel Sequence::getDistanceModel() const
+{
+ return m_sequence->getDistanceModel();
+}
+
+void Sequence::setDistanceModel(DistanceModel model)
+{
+ m_sequence->setDistanceModel(model);
+}
+
+AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type)
+{
+ return m_sequence->getAnimProperty(type);
+}
+
+std::shared_ptr<SequenceEntry> Sequence::add(std::shared_ptr<ISound> sound, float begin, float end, float skip)
+{
+ return m_sequence->add(sound, begin, end, skip);
+}
+
+void Sequence::remove(std::shared_ptr<SequenceEntry> entry)
+{
+ m_sequence->remove(entry);
+}
+
+std::shared_ptr<IReader> Sequence::createQualityReader()
+{
+ return std::shared_ptr<IReader>(new SequenceReader(m_sequence, true));
+}
+
+std::shared_ptr<IReader> Sequence::createReader()
+{
+ return std::shared_ptr<IReader>(new SequenceReader(m_sequence));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp
new file mode 100644
index 00000000000..fb920acc1a8
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceData.cpp
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/SequenceData.h"
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceEntry.h"
+
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceData::SequenceData(Specs specs, float fps, bool muted) :
+ m_specs(specs),
+ m_status(0),
+ m_entry_status(0),
+ m_id(0),
+ m_muted(muted),
+ m_fps(fps),
+ m_speed_of_sound(343.3f),
+ m_doppler_factor(1),
+ m_distance_model(DISTANCE_MODEL_INVERSE_CLAMPED),
+ m_volume(1, 1.0f),
+ m_location(3),
+ m_orientation(4)
+{
+ Quaternion q;
+ m_orientation.write(q.get());
+ float f = 1;
+ m_volume.write(&f);
+}
+
+SequenceData::~SequenceData()
+{
+}
+
+void SequenceData::lock()
+{
+ m_mutex.lock();
+}
+
+void SequenceData::unlock()
+{
+ m_mutex.unlock();
+}
+
+Specs SequenceData::getSpecs()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ return m_specs;
+}
+
+void SequenceData::setSpecs(Specs specs)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_specs = specs;
+ m_status++;
+}
+
+float SequenceData::getFPS() const
+{
+ return m_fps;
+}
+
+void SequenceData::setFPS(float fps)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_fps = fps;
+}
+
+void SequenceData::mute(bool muted)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_muted = muted;
+}
+
+bool SequenceData::isMuted() const
+{
+ return m_muted;
+}
+
+float SequenceData::getSpeedOfSound() const
+{
+ return m_speed_of_sound;
+}
+
+void SequenceData::setSpeedOfSound(float speed)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_speed_of_sound = speed;
+ m_status++;
+}
+
+float SequenceData::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void SequenceData::setDopplerFactor(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_doppler_factor = factor;
+ m_status++;
+}
+
+DistanceModel SequenceData::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void SequenceData::setDistanceModel(DistanceModel model)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_model = model;
+ m_status++;
+}
+
+AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type)
+{
+ switch(type)
+ {
+ case AP_VOLUME:
+ return &m_volume;
+ case AP_LOCATION:
+ return &m_location;
+ case AP_ORIENTATION:
+ return &m_orientation;
+ default:
+ return nullptr;
+ }
+}
+
+std::shared_ptr<SequenceEntry> SequenceData::add(std::shared_ptr<ISound> sound, float begin, float end, float skip)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ std::shared_ptr<SequenceEntry> entry = std::shared_ptr<SequenceEntry>(new SequenceEntry(sound, begin, end, skip, m_id++));
+
+ m_entries.push_back(entry);
+ m_entry_status++;
+
+ return entry;
+}
+
+void SequenceData::remove(std::shared_ptr<SequenceEntry> entry)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_entries.remove(entry);
+ m_entry_status++;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceEntry.cpp b/extern/audaspace/src/sequence/SequenceEntry.cpp
new file mode 100644
index 00000000000..de538199d7d
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceEntry.cpp
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/SequenceEntry.h"
+#include "sequence/SequenceReader.h"
+
+#include <limits>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, float begin, float end, float skip, int id) :
+ m_status(0),
+ m_pos_status(1),
+ m_sound_status(0),
+ m_id(id),
+ m_sound(sound),
+ m_begin(begin),
+ m_end(end),
+ m_skip(skip),
+ m_muted(false),
+ m_relative(true),
+ m_volume_max(1.0f),
+ m_volume_min(0),
+ m_distance_max(std::numeric_limits<float>::max()),
+ m_distance_reference(1.0f),
+ m_attenuation(1.0f),
+ m_cone_angle_outer(360),
+ m_cone_angle_inner(360),
+ m_cone_volume_outer(0),
+ m_volume(1, 1.0f),
+ m_pitch(1, 1.0f),
+ m_location(3),
+ m_orientation(4)
+{
+ Quaternion q;
+ m_orientation.write(q.get());
+ float f = 1;
+ m_volume.write(&f);
+ m_pitch.write(&f);
+}
+
+SequenceEntry::~SequenceEntry()
+{
+}
+
+void SequenceEntry::lock()
+{
+ m_mutex.lock();
+}
+
+void SequenceEntry::unlock()
+{
+ m_mutex.unlock();
+}
+
+std::shared_ptr<ISound> SequenceEntry::getSound()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+ return m_sound;
+}
+
+void SequenceEntry::setSound(std::shared_ptr<ISound> sound)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_sound.get() != sound.get())
+ {
+ m_sound = sound;
+ m_sound_status++;
+ }
+}
+
+void SequenceEntry::move(float begin, float end, float skip)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_begin != begin || m_skip != skip || m_end != end)
+ {
+ m_begin = begin;
+ m_skip = skip;
+ m_end = end;
+ m_pos_status++;
+ }
+}
+
+bool SequenceEntry::isMuted()
+{
+ return m_muted;
+}
+
+void SequenceEntry::mute(bool mute)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_muted = mute;
+}
+
+int SequenceEntry::getID() const
+{
+ return m_id;
+}
+
+AnimateableProperty* SequenceEntry::getAnimProperty(AnimateablePropertyType type)
+{
+ switch(type)
+ {
+ case AP_VOLUME:
+ return &m_volume;
+ case AP_PITCH:
+ return &m_pitch;
+ case AP_PANNING:
+ return &m_panning;
+ case AP_LOCATION:
+ return &m_location;
+ case AP_ORIENTATION:
+ return &m_orientation;
+ default:
+ return nullptr;
+ }
+}
+
+bool SequenceEntry::isRelative()
+{
+ return m_relative;
+}
+
+void SequenceEntry::setRelative(bool relative)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_relative != relative)
+ {
+ m_relative = relative;
+ m_status++;
+ }
+}
+
+float SequenceEntry::getVolumeMaximum()
+{
+ return m_volume_max;
+}
+
+void SequenceEntry::setVolumeMaximum(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_volume_max = volume;
+ m_status++;
+}
+
+float SequenceEntry::getVolumeMinimum()
+{
+ return m_volume_min;
+}
+
+void SequenceEntry::setVolumeMinimum(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_volume_min = volume;
+ m_status++;
+}
+
+float SequenceEntry::getDistanceMaximum()
+{
+ return m_distance_max;
+}
+
+void SequenceEntry::setDistanceMaximum(float distance)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_max = distance;
+ m_status++;
+}
+
+float SequenceEntry::getDistanceReference()
+{
+ return m_distance_reference;
+}
+
+void SequenceEntry::setDistanceReference(float distance)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_reference = distance;
+ m_status++;
+}
+
+float SequenceEntry::getAttenuation()
+{
+ return m_attenuation;
+}
+
+void SequenceEntry::setAttenuation(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_attenuation = factor;
+ m_status++;
+}
+
+float SequenceEntry::getConeAngleOuter()
+{
+ return m_cone_angle_outer;
+}
+
+void SequenceEntry::setConeAngleOuter(float angle)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_angle_outer = angle;
+ m_status++;
+}
+
+float SequenceEntry::getConeAngleInner()
+{
+ return m_cone_angle_inner;
+}
+
+void SequenceEntry::setConeAngleInner(float angle)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_angle_inner = angle;
+ m_status++;
+}
+
+float SequenceEntry::getConeVolumeOuter()
+{
+ return m_cone_volume_outer;
+}
+
+void SequenceEntry::setConeVolumeOuter(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_volume_outer = volume;
+ m_status++;
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp
index aa742f7b8db..140b1fbd94a 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/extern/audaspace/src/sequence/SequenceHandle.cpp
@@ -1,39 +1,31 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerHandle.cpp
- * \ingroup audaspaceintern
- */
+#include "SequenceHandle.h"
+#include "sequence/SequenceEntry.h"
+#include "devices/ReadDevice.h"
+#include "Exception.h"
-
-#include "AUD_SequencerHandle.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_MutexLock.h"
+#include <mutex>
#define KEEP_TIME 10
-void AUD_SequencerHandle::start()
+AUD_NAMESPACE_BEGIN
+
+void SequenceHandle::start()
{
// we already tried to start, aborting
if(!m_valid)
@@ -42,7 +34,7 @@ void AUD_SequencerHandle::start()
// in case the sound is playing, we need to stop first
stop();
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
// let's try playing
if(m_entry->m_sound.get())
@@ -50,9 +42,9 @@ void AUD_SequencerHandle::start()
try
{
m_handle = m_device.play(m_entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
+ m_3dhandle = std::dynamic_pointer_cast<I3DHandle>(m_handle);
}
- catch(AUD_Exception&)
+ catch(Exception&)
{
// handle stays invalid in case we get an exception
}
@@ -65,9 +57,9 @@ void AUD_SequencerHandle::start()
m_valid = m_handle.get();
}
-bool AUD_SequencerHandle::updatePosition(float position)
+bool SequenceHandle::updatePosition(float position)
{
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
if(m_handle.get())
{
@@ -116,7 +108,7 @@ bool AUD_SequencerHandle::updatePosition(float position)
return false;
}
-AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
+SequenceHandle::SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device) :
m_entry(entry),
m_valid(true),
m_status(0),
@@ -126,12 +118,12 @@ AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> e
{
}
-AUD_SequencerHandle::~AUD_SequencerHandle()
+SequenceHandle::~SequenceHandle()
{
stop();
}
-int AUD_SequencerHandle::compare(boost::shared_ptr<AUD_SequencerEntry> entry) const
+int SequenceHandle::compare(std::shared_ptr<SequenceEntry> entry) const
{
if(m_entry->getID() < entry->getID())
return -1;
@@ -140,15 +132,15 @@ int AUD_SequencerHandle::compare(boost::shared_ptr<AUD_SequencerEntry> entry) co
return 1;
}
-void AUD_SequencerHandle::stop()
+void SequenceHandle::stop()
{
if(m_handle.get())
m_handle->stop();
- m_handle = boost::shared_ptr<AUD_IHandle>();
- m_3dhandle = boost::shared_ptr<AUD_I3DHandle>();
+ m_handle = nullptr;
+ m_3dhandle = nullptr;
}
-void AUD_SequencerHandle::update(float position, float frame, float fps)
+void SequenceHandle::update(float position, float frame, float fps)
{
if(m_sound_status != m_entry->m_sound_status)
{
@@ -185,7 +177,7 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
}
}
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
if(m_pos_status != m_entry->m_pos_status)
{
m_pos_status = m_entry->m_pos_status;
@@ -200,8 +192,6 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
if(m_status != m_entry->m_status)
{
- m_status = m_entry->m_status;
-
m_3dhandle->setRelative(m_entry->m_relative);
m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
@@ -211,6 +201,8 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
+
+ m_status = m_entry->m_status;
}
float value;
@@ -220,24 +212,24 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
m_entry->m_pitch.read(frame, &value);
m_handle->setPitch(value);
m_entry->m_panning.read(frame, &value);
- AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+ SoftwareDevice::setPanning(m_handle.get(), value);
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
+ Vector3 v, v2;
+ Quaternion q;
m_entry->m_orientation.read(frame, q.get());
- m_3dhandle->setSourceOrientation(q);
+ m_3dhandle->setOrientation(q);
m_entry->m_location.read(frame, v.get());
- m_3dhandle->setSourceLocation(v);
+ m_3dhandle->setLocation(v);
m_entry->m_location.read(frame + 1, v2.get());
v2 -= v;
- m_3dhandle->setSourceVelocity(v2 * fps);
+ m_3dhandle->setVelocity(v2 * fps);
if(m_entry->m_muted)
m_handle->setVolume(0);
}
-bool AUD_SequencerHandle::seek(float position)
+bool SequenceHandle::seek(float position)
{
if(!m_valid)
// sound not valid, aborting
@@ -247,7 +239,7 @@ bool AUD_SequencerHandle::seek(float position)
// no handle, aborting
return false;
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
float seekpos = position - m_entry->m_begin;
if(seekpos < 0)
seekpos = 0;
@@ -257,3 +249,5 @@ bool AUD_SequencerHandle::seek(float position)
return true;
}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/extern/audaspace/src/sequence/SequenceHandle.h
index 306df4a84b9..9a77489a8f8 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.h
+++ b/extern/audaspace/src/sequence/SequenceHandle.h
@@ -1,55 +1,46 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerHandle.h
- * \ingroup audaspaceintern
- */
+#pragma once
+#include "Audaspace.h"
-#ifndef __AUD_SEQUENCERHANDLE_H__
-#define __AUD_SEQUENCERHANDLE_H__
+#include <memory>
-#include "AUD_SequencerEntry.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DHandle.h"
+AUD_NAMESPACE_BEGIN
-class AUD_ReadDevice;
+class ReadDevice;
+class IHandle;
+class I3DHandle;
+class SequenceEntry;
/**
* Represents a playing sequenced entry.
*/
-class AUD_SequencerHandle
+class SequenceHandle
{
private:
/// The entry this handle belongs to.
- boost::shared_ptr<AUD_SequencerEntry> m_entry;
+ std::shared_ptr<SequenceEntry> m_entry;
/// The handle in the read device.
- boost::shared_ptr<AUD_IHandle> m_handle;
+ std::shared_ptr<IHandle> m_handle;
/// The 3D handle in the read device.
- boost::shared_ptr<AUD_I3DHandle> m_3dhandle;
+ std::shared_ptr<I3DHandle> m_3dhandle;
/// Whether the sound is playable.
bool m_valid;
@@ -64,7 +55,11 @@ private:
int m_sound_status;
/// The read device this handle is played on.
- AUD_ReadDevice& m_device;
+ ReadDevice& m_device;
+
+ // delete copy constructor and operator=
+ SequenceHandle(const SequenceHandle&) = delete;
+ SequenceHandle& operator=(const SequenceHandle&) = delete;
/**
* Starts playing back the handle.
@@ -84,19 +79,19 @@ public:
* \param entry The entry this handle plays.
* \param device The read device to play on.
*/
- AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device);
+ SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device);
/**
* Destroys the handle.
*/
- ~AUD_SequencerHandle();
+ ~SequenceHandle();
/**
* Compares whether this handle is playing the same entry as supplied.
* \param entry The entry to compare to.
* \return Whether the entries ID is smaller, equal or bigger.
*/
- int compare(boost::shared_ptr<AUD_SequencerEntry> entry) const;
+ int compare(std::shared_ptr<SequenceEntry> entry) const;
/**
* Stops playing back the handle.
@@ -119,4 +114,4 @@ public:
bool seek(float position);
};
-#endif //__AUD_SEQUENCERHANDLE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceReader.cpp b/extern/audaspace/src/sequence/SequenceReader.cpp
new file mode 100644
index 00000000000..38647aaeadf
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceReader.cpp
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceData.h"
+#include "Exception.h"
+#include "SequenceHandle.h"
+
+#include <algorithm>
+#include <mutex>
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceReader::SequenceReader(std::shared_ptr<SequenceData> sequence, bool quality) :
+ m_position(0), m_device(sequence->m_specs), m_sequence(sequence), m_status(0), m_entry_status(0)
+{
+ m_device.setQuality(quality);
+}
+
+SequenceReader::~SequenceReader()
+{
+}
+
+bool SequenceReader::isSeekable() const
+{
+ return true;
+}
+
+void SequenceReader::seek(int position)
+{
+ if(position < 0)
+ return;
+
+ m_position = position;
+
+ for(auto& handle : m_handles)
+ {
+ handle->seek(position / m_sequence->m_specs.rate);
+ }
+}
+
+int SequenceReader::getLength() const
+{
+ return -1;
+}
+
+int SequenceReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SequenceReader::getSpecs() const
+{
+ return m_sequence->m_specs;
+}
+
+void SequenceReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ std::lock_guard<ILockable> lock(*m_sequence);
+
+ if(m_sequence->m_status != m_status)
+ {
+ m_device.changeSpecs(m_sequence->m_specs);
+ m_device.setSpeedOfSound(m_sequence->m_speed_of_sound);
+ m_device.setDistanceModel(m_sequence->m_distance_model);
+ m_device.setDopplerFactor(m_sequence->m_doppler_factor);
+
+ m_status = m_sequence->m_status;
+ }
+
+ if(m_sequence->m_entry_status != m_entry_status)
+ {
+ std::list<std::shared_ptr<SequenceHandle> > handles;
+
+ auto hit = m_handles.begin();
+ auto eit = m_sequence->m_entries.begin();
+
+ int result;
+ std::shared_ptr<SequenceHandle> handle;
+
+ while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
+ {
+ handle = *hit;
+ std::shared_ptr<SequenceEntry> entry = *eit;
+
+ result = handle->compare(entry);
+
+ if(result < 0)
+ {
+ try
+ {
+ handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(entry, m_device));
+ handles.push_back(handle);
+ }
+ catch(Exception&)
+ {
+ }
+ eit++;
+ }
+ else if(result == 0)
+ {
+ handles.push_back(handle);
+ hit++;
+ eit++;
+ }
+ else
+ {
+ handle->stop();
+ hit++;
+ }
+ }
+
+ while(hit != m_handles.end())
+ {
+ (*hit)->stop();
+ hit++;
+ }
+
+ while(eit != m_sequence->m_entries.end())
+ {
+ try
+ {
+ handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(*eit, m_device));
+ handles.push_back(handle);
+ }
+ catch(Exception&)
+ {
+ }
+ eit++;
+ }
+
+ m_handles = handles;
+
+ m_entry_status = m_sequence->m_entry_status;
+ }
+
+ Specs specs = m_sequence->m_specs;
+ int pos = 0;
+ float time = float(m_position) / float(specs.rate);
+ float volume, frame;
+ int len, cfra;
+ Vector3 v, v2;
+ Quaternion q;
+
+
+ while(pos < length)
+ {
+ frame = time * m_sequence->m_fps;
+ cfra = int(std::floor(frame));
+
+ len = int(std::ceil((cfra + 1) / m_sequence->m_fps * specs.rate)) - m_position;
+ len = std::min(length - pos, len);
+ len = std::max(len, 1);
+
+ for(auto& handle : m_handles)
+ {
+ handle->update(time, frame, m_sequence->m_fps);
+ }
+
+ m_sequence->m_volume.read(frame, &volume);
+ if(m_sequence->m_muted)
+ volume = 0.0f;
+ m_device.setVolume(volume);
+
+ m_sequence->m_orientation.read(frame, q.get());
+ m_device.setListenerOrientation(q);
+ m_sequence->m_location.read(frame, v.get());
+ m_device.setListenerLocation(v);
+ m_sequence->m_location.read(frame + 1, v2.get());
+ v2 -= v;
+ m_device.setListenerVelocity(v2 * m_sequence->m_fps);
+
+ m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
+
+ pos += len;
+ time += float(len) / float(specs.rate);
+ }
+
+ m_position += length;
+
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Superpose.cpp b/extern/audaspace/src/sequence/Superpose.cpp
new file mode 100644
index 00000000000..3d13f7db627
--- /dev/null
+++ b/extern/audaspace/src/sequence/Superpose.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/Superpose.h"
+#include "sequence/SuperposeReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Superpose::Superpose(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
+ m_sound1(sound1), m_sound2(sound2)
+{
+}
+
+std::shared_ptr<IReader> Superpose::createReader()
+{
+ std::shared_ptr<IReader> reader1 = m_sound1->createReader();
+ std::shared_ptr<IReader> reader2 = m_sound2->createReader();
+
+ return std::shared_ptr<IReader>(new SuperposeReader(reader1, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SuperposeReader.cpp b/extern/audaspace/src/sequence/SuperposeReader.cpp
new file mode 100644
index 00000000000..9206a7a96ef
--- /dev/null
+++ b/extern/audaspace/src/sequence/SuperposeReader.cpp
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "sequence/SuperposeReader.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SuperposeReader::SuperposeReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
+ m_reader1(reader1), m_reader2(reader2)
+{
+}
+
+SuperposeReader::~SuperposeReader()
+{
+}
+
+bool SuperposeReader::isSeekable() const
+{
+ return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void SuperposeReader::seek(int position)
+{
+ m_reader1->seek(position);
+ m_reader2->seek(position);
+}
+
+int SuperposeReader::getLength() const
+{
+ int len1 = m_reader1->getLength();
+ int len2 = m_reader2->getLength();
+ if((len1 < 0) || (len2 < 0))
+ return -1;
+ return std::min(len1, len2);
+}
+
+int SuperposeReader::getPosition() const
+{
+ int pos1 = m_reader1->getPosition();
+ int pos2 = m_reader2->getPosition();
+ return std::max(pos1, pos2);
+}
+
+Specs SuperposeReader::getSpecs() const
+{
+ return m_reader1->getSpecs();
+}
+
+void SuperposeReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader1->getSpecs();
+ Specs s2 = m_reader2->getSpecs();
+ if(!AUD_COMPARE_SPECS(specs, s2))
+ AUD_THROW(StateException, "Two readers with different specifiactions cannot be superposed.");
+
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer.assureSize(length * samplesize);
+
+ int len1 = length;
+ m_reader1->read(len1, eos, buffer);
+
+ if(len1 < length)
+ std::memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
+
+ int len2 = length;
+ bool eos2;
+ sample_t* buf = m_buffer.getBuffer();
+ m_reader2->read(len2, eos2, buf);
+
+ for(int i = 0; i < len2 * specs.channels; i++)
+ buffer[i] += buf[i];
+
+ length = std::max(len1, len2);
+ eos &= eos2;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/Barrier.cpp b/extern/audaspace/src/util/Barrier.cpp
new file mode 100644
index 00000000000..3347a38092b
--- /dev/null
+++ b/extern/audaspace/src/util/Barrier.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "util/Barrier.h"
+
+AUD_NAMESPACE_BEGIN
+Barrier::Barrier(unsigned int count) :
+ m_threshold(count), m_count(count), m_generation(0)
+{
+}
+
+Barrier::~Barrier()
+{
+}
+
+void Barrier::wait()
+{
+ std::unique_lock<std::mutex> lck(m_mutex);
+ int gen = m_generation;
+ if(!--m_count)
+ {
+ m_count = m_threshold;
+ m_generation++;
+ m_condition.notify_all();
+ }
+ else
+ m_condition.wait(lck, [this, gen] { return gen != m_generation; });
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/util/Buffer.cpp b/extern/audaspace/src/util/Buffer.cpp
new file mode 100644
index 00000000000..d212278cacc
--- /dev/null
+++ b/extern/audaspace/src/util/Buffer.cpp
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "util/Buffer.h"
+
+#include <algorithm>
+#include <cstring>
+#include <cstdlib>
+
+#define ALIGNMENT 32
+#define ALIGN(a) (a + ALIGNMENT - ((long long)a & (ALIGNMENT-1)))
+
+AUD_NAMESPACE_BEGIN
+
+Buffer::Buffer(int size)
+{
+ m_size = size;
+ m_buffer = (data_t*) std::malloc(size + ALIGNMENT);
+}
+
+Buffer::~Buffer()
+{
+ std::free(m_buffer);
+}
+
+sample_t* Buffer::getBuffer() const
+{
+ return (sample_t*) ALIGN(m_buffer);
+}
+
+int Buffer::getSize() const
+{
+ return m_size;
+}
+
+void Buffer::resize(int size, bool keep)
+{
+ if(keep)
+ {
+ data_t* buffer = (data_t*) std::malloc(size + ALIGNMENT);
+
+ std::memcpy(ALIGN(buffer), ALIGN(m_buffer), std::min(size, m_size));
+
+ std::free(m_buffer);
+ m_buffer = buffer;
+ }
+ else
+ m_buffer = (data_t*) std::realloc(m_buffer, size + ALIGNMENT);
+
+ m_size = size;
+}
+
+void Buffer::assureSize(int size, bool keep)
+{
+ if(m_size < size)
+ resize(size, keep);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/BufferReader.cpp b/extern/audaspace/src/util/BufferReader.cpp
new file mode 100644
index 00000000000..37744420ab8
--- /dev/null
+++ b/extern/audaspace/src/util/BufferReader.cpp
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "util/BufferReader.h"
+#include "util/Buffer.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BufferReader::BufferReader(std::shared_ptr<Buffer> buffer,
+ Specs specs) :
+ m_position(0), m_buffer(buffer), m_specs(specs)
+{
+}
+
+bool BufferReader::isSeekable() const
+{
+ return true;
+}
+
+void BufferReader::seek(int position)
+{
+ m_position = position;
+}
+
+int BufferReader::getLength() const
+{
+ return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
+}
+
+int BufferReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs BufferReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void BufferReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ eos = false;
+
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;
+
+ // in case the end of the buffer is reached
+ if(m_buffer->getSize() < (m_position + length) * sample_size)
+ {
+ length = m_buffer->getSize() / sample_size - m_position;
+ eos = true;
+ }
+
+ if(length < 0)
+ {
+ length = 0;
+ return;
+ }
+
+ m_position += length;
+ std::memcpy(buffer, buf, length * sample_size);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/FFTPlan.cpp b/extern/audaspace/src/util/FFTPlan.cpp
new file mode 100644
index 00000000000..5e99dbff247
--- /dev/null
+++ b/extern/audaspace/src/util/FFTPlan.cpp
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "util/FFTPlan.h"
+
+AUD_NAMESPACE_BEGIN
+FFTPlan::FFTPlan(double measureTime) :
+ FFTPlan(DEFAULT_N, measureTime)
+{
+}
+
+FFTPlan::FFTPlan(int n, double measureTime) :
+ m_N(n), m_bufferSize(((n/2)+1)*2*sizeof(fftwf_complex))
+{
+ fftwf_set_timelimit(measureTime);
+ void* buf = fftwf_malloc(m_bufferSize);
+ m_fftPlanR2C = fftwf_plan_dft_r2c_1d(m_N, (float*)buf, (fftwf_complex*)buf, FFTW_EXHAUSTIVE);
+ m_fftPlanC2R = fftwf_plan_dft_c2r_1d(m_N, (fftwf_complex*)buf, (float*)buf, FFTW_EXHAUSTIVE);
+ fftwf_free(buf);
+}
+
+FFTPlan::~FFTPlan()
+{
+ fftwf_destroy_plan(m_fftPlanC2R);
+ fftwf_destroy_plan(m_fftPlanR2C);
+}
+
+int FFTPlan::getSize()
+{
+ return m_N;
+}
+
+void FFTPlan::FFT(void* buffer)
+{
+ fftwf_execute_dft_r2c(m_fftPlanR2C, (float*)buffer, (fftwf_complex*)buffer);
+}
+
+void FFTPlan::IFFT(void* buffer)
+{
+ fftwf_execute_dft_c2r(m_fftPlanC2R, (fftwf_complex*)buffer, (float*)buffer);
+}
+
+void* FFTPlan::getBuffer()
+{
+ return fftwf_malloc(m_bufferSize);
+}
+
+void FFTPlan::freeBuffer(void* buffer)
+{
+ fftwf_free(buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/StreamBuffer.cpp b/extern/audaspace/src/util/StreamBuffer.cpp
new file mode 100644
index 00000000000..b87b363377d
--- /dev/null
+++ b/extern/audaspace/src/util/StreamBuffer.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+
+#include "util/StreamBuffer.h"
+#include "util/BufferReader.h"
+#include "util/Buffer.h"
+
+// 5 sec * 48000 samples/sec * 4 bytes/sample * 6 channels
+#define BUFFER_RESIZE_BYTES 5760000
+
+AUD_NAMESPACE_BEGIN
+
+StreamBuffer::StreamBuffer(std::shared_ptr<ISound> sound) :
+ m_buffer(new Buffer())
+{
+ std::shared_ptr<IReader> reader = sound->createReader();
+
+ m_specs = reader->getSpecs();
+
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int length;
+ int index = 0;
+ bool eos = false;
+
+ // get an approximated size if possible
+ int size = reader->getLength();
+
+ if(size <= 0)
+ size = BUFFER_RESIZE_BYTES / sample_size;
+ else
+ size += m_specs.rate;
+
+ // as long as the end of the stream is not reached
+ while(!eos)
+ {
+ // increase
+ m_buffer->resize(size*sample_size, true);
+
+ // read more
+ length = size-index;
+ reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels);
+ if(index == m_buffer->getSize() / sample_size)
+ size += BUFFER_RESIZE_BYTES / sample_size;
+ index += length;
+ }
+
+ m_buffer->resize(index * sample_size, true);
+}
+
+StreamBuffer::StreamBuffer(std::shared_ptr<Buffer> buffer, Specs specs) :
+ m_buffer(buffer), m_specs(specs)
+{
+}
+
+std::shared_ptr<Buffer> StreamBuffer::getBuffer()
+{
+ return m_buffer;
+}
+
+Specs StreamBuffer::getSpecs()
+{
+ return m_specs;
+}
+
+std::shared_ptr<IReader> StreamBuffer::createReader()
+{
+ return std::shared_ptr<IReader>(new BufferReader(m_buffer, m_specs));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/ThreadPool.cpp b/extern/audaspace/src/util/ThreadPool.cpp
new file mode 100644
index 00000000000..74051902c3b
--- /dev/null
+++ b/extern/audaspace/src/util/ThreadPool.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+******************************************************************************/
+
+#include "util/ThreadPool.h"
+
+AUD_NAMESPACE_BEGIN
+
+ThreadPool::ThreadPool(unsigned int count) :
+ m_stopFlag(false), m_numThreads(count)
+{
+ for(unsigned int i = 0; i < count; i++)
+ m_threads.emplace_back(&ThreadPool::threadFunction, this);
+}
+
+ThreadPool::~ThreadPool()
+{
+ m_mutex.lock();
+ m_stopFlag = true;
+ m_mutex.unlock();
+ m_condition.notify_all();
+ for(unsigned int i = 0; i < m_threads.size(); i++)
+ m_threads[i].join();
+}
+
+unsigned int ThreadPool::getNumOfThreads()
+{
+ return m_numThreads;
+}
+
+void ThreadPool::threadFunction()
+{
+ while(true)
+ {
+ std::function<void()> task;
+ {
+ std::unique_lock<std::mutex> lock(m_mutex);
+ m_condition.wait(lock, [this] { return m_stopFlag || !m_queue.empty(); });
+ if(m_stopFlag && m_queue.empty())
+ return;
+ task = std::move(m_queue.front());
+ this->m_queue.pop();
+ }
+ task();
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index dd446613fd0..e359a631532 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -24,9 +24,6 @@ remove_strict_flags()
if(CMAKE_COMPILER_IS_GNUCC)
remove_cc_flag("-Wunused-macros")
endif()
-
-if(WITH_SYSTEM_AUDASPACE)
-
set(INC
.
)
@@ -52,305 +49,4 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-else()
-
-set(INC
- .
- FX
- intern
- ../ffmpeg
-)
-
-set(INC_SYS
- ${PTHREADS_INCLUDE_DIRS}
- ${BOOST_INCLUDE_DIR}
-)
-
-set(SRC
- FX/AUD_AccumulatorFactory.cpp
- FX/AUD_BandpassCalculator.cpp
- FX/AUD_BaseIIRFilterReader.cpp
- FX/AUD_ButterworthCalculator.cpp
- FX/AUD_ButterworthFactory.cpp
- FX/AUD_CallbackIIRFilterReader.cpp
- FX/AUD_DelayFactory.cpp
- FX/AUD_DelayReader.cpp
- FX/AUD_DoubleFactory.cpp
- FX/AUD_DoubleReader.cpp
- FX/AUD_DynamicIIRFilterFactory.cpp
- FX/AUD_DynamicIIRFilterReader.cpp
- FX/AUD_EffectFactory.cpp
- FX/AUD_EffectReader.cpp
- FX/AUD_EnvelopeFactory.cpp
- FX/AUD_FaderFactory.cpp
- FX/AUD_FaderReader.cpp
- FX/AUD_HighpassCalculator.cpp
- FX/AUD_HighpassFactory.cpp
- FX/AUD_IIRFilterFactory.cpp
- FX/AUD_IIRFilterReader.cpp
- FX/AUD_LimiterFactory.cpp
- FX/AUD_LimiterReader.cpp
- FX/AUD_LoopFactory.cpp
- FX/AUD_LoopReader.cpp
- FX/AUD_LowpassCalculator.cpp
- FX/AUD_LowpassFactory.cpp
- FX/AUD_PingPongFactory.cpp
- FX/AUD_PitchFactory.cpp
- FX/AUD_PitchReader.cpp
- FX/AUD_RectifyFactory.cpp
- FX/AUD_ReverseFactory.cpp
- FX/AUD_ReverseReader.cpp
- FX/AUD_SquareFactory.cpp
- FX/AUD_SumFactory.cpp
- FX/AUD_SuperposeFactory.cpp
- FX/AUD_SuperposeReader.cpp
- FX/AUD_VolumeFactory.cpp
-
- intern/AUD_3DMath.h
- intern/AUD_AnimateableProperty.cpp
- intern/AUD_AnimateableProperty.h
- intern/AUD_Buffer.cpp
- intern/AUD_Buffer.h
- intern/AUD_BufferReader.cpp
- intern/AUD_BufferReader.h
- intern/AUD_C-API.cpp
- intern/AUD_C-API.h
- intern/AUD_ChannelMapperFactory.cpp
- intern/AUD_ChannelMapperFactory.h
- intern/AUD_ChannelMapperReader.cpp
- intern/AUD_ChannelMapperReader.h
- intern/AUD_ConverterFactory.cpp
- intern/AUD_ConverterFactory.h
- intern/AUD_ConverterFunctions.cpp
- intern/AUD_ConverterFunctions.h
- intern/AUD_ConverterReader.cpp
- intern/AUD_ConverterReader.h
- intern/AUD_FileFactory.cpp
- intern/AUD_FileFactory.h
- intern/AUD_FileWriter.cpp
- intern/AUD_FileWriter.h
- intern/AUD_I3DDevice.h
- intern/AUD_I3DHandle.h
- intern/AUD_IDevice.h
- intern/AUD_IFactory.h
- intern/AUD_IHandle.h
- intern/AUD_ILockable.h
- intern/AUD_IReader.h
- intern/AUD_IWriter.h
- intern/AUD_JOSResampleFactory.cpp
- intern/AUD_JOSResampleFactory.h
- intern/AUD_JOSResampleReader.cpp
- intern/AUD_JOSResampleReader.h
- intern/AUD_LinearResampleFactory.cpp
- intern/AUD_LinearResampleFactory.h
- intern/AUD_LinearResampleReader.cpp
- intern/AUD_LinearResampleReader.h
- intern/AUD_Mixer.cpp
- intern/AUD_Mixer.h
- intern/AUD_MixerFactory.cpp
- intern/AUD_MixerFactory.h
- intern/AUD_MutexLock.h
- intern/AUD_NULLDevice.cpp
- intern/AUD_NULLDevice.h
- intern/AUD_PyInit.h
- intern/AUD_ReadDevice.cpp
- intern/AUD_ReadDevice.h
- intern/AUD_ResampleFactory.h
- intern/AUD_ResampleReader.cpp
- intern/AUD_ResampleReader.h
- intern/AUD_Sequencer.cpp
- intern/AUD_Sequencer.h
- intern/AUD_SequencerEntry.cpp
- intern/AUD_SequencerEntry.h
- intern/AUD_SequencerFactory.cpp
- intern/AUD_SequencerFactory.h
- intern/AUD_SequencerHandle.cpp
- intern/AUD_SequencerHandle.h
- intern/AUD_SequencerReader.cpp
- intern/AUD_SequencerReader.h
- intern/AUD_Set.cpp
- intern/AUD_Set.h
- intern/AUD_SilenceFactory.cpp
- intern/AUD_SilenceFactory.h
- intern/AUD_SilenceReader.cpp
- intern/AUD_SilenceReader.h
- intern/AUD_SinusFactory.cpp
- intern/AUD_SinusFactory.h
- intern/AUD_SinusReader.cpp
- intern/AUD_SinusReader.h
- intern/AUD_SoftwareDevice.cpp
- intern/AUD_SoftwareDevice.h
- intern/AUD_Space.h
- intern/AUD_StreamBufferFactory.cpp
- intern/AUD_StreamBufferFactory.h
-
- FX/AUD_AccumulatorFactory.h
- FX/AUD_BandpassCalculator.h
- FX/AUD_BaseIIRFilterReader.h
- FX/AUD_ButterworthCalculator.h
- FX/AUD_ButterworthFactory.h
- FX/AUD_CallbackIIRFilterReader.h
- FX/AUD_DelayFactory.h
- FX/AUD_DelayReader.h
- FX/AUD_DoubleFactory.h
- FX/AUD_DoubleReader.h
- FX/AUD_IDynamicIIRFilterCalculator.h
- FX/AUD_DynamicIIRFilterFactory.h
- FX/AUD_DynamicIIRFilterReader.h
- FX/AUD_EffectFactory.h
- FX/AUD_EffectReader.h
- FX/AUD_EnvelopeFactory.h
- FX/AUD_FaderFactory.h
- FX/AUD_FaderReader.h
- FX/AUD_HighpassCalculator.h
- FX/AUD_HighpassFactory.h
- FX/AUD_IIRFilterFactory.h
- FX/AUD_IIRFilterReader.h
- FX/AUD_LimiterFactory.h
- FX/AUD_LimiterReader.h
- FX/AUD_LoopFactory.h
- FX/AUD_LoopReader.h
- FX/AUD_LowpassCalculator.h
- FX/AUD_LowpassFactory.h
- FX/AUD_PingPongFactory.h
- FX/AUD_PitchFactory.h
- FX/AUD_PitchReader.h
- FX/AUD_RectifyFactory.h
- FX/AUD_ReverseFactory.h
- FX/AUD_ReverseReader.h
- FX/AUD_SquareFactory.h
- FX/AUD_SumFactory.h
- FX/AUD_SuperposeFactory.h
- FX/AUD_SuperposeReader.h
- FX/AUD_VolumeFactory.h
-)
-
-if(WITH_CODEC_FFMPEG)
- add_definitions(-DWITH_FFMPEG)
- list(APPEND INC
- ffmpeg
- )
- list(APPEND INC_SYS
- ${FFMPEG_INCLUDE_DIRS}
- )
- list(APPEND SRC
- ffmpeg/AUD_FFMPEGFactory.cpp
- ffmpeg/AUD_FFMPEGReader.cpp
- ffmpeg/AUD_FFMPEGWriter.cpp
-
- ffmpeg/AUD_FFMPEGFactory.h
- ffmpeg/AUD_FFMPEGReader.h
- ffmpeg/AUD_FFMPEGWriter.h
- )
-
- remove_strict_flags_file(
- ffmpeg/AUD_FFMPEGFactory.cpp
- ffmpeg/AUD_FFMPEGReader.cpp
- ffmpeg/AUD_FFMPEGWriter.cpp
- )
-endif()
-
-if(WITH_SDL)
- add_definitions(-DWITH_SDL)
- list(APPEND INC
- SDL
- )
- list(APPEND INC_SYS
- ${SDL_INCLUDE_DIR}
- )
- list(APPEND SRC
- SDL/AUD_SDLDevice.cpp
-
- SDL/AUD_SDLDevice.h
- )
-endif()
-
-if(WITH_OPENAL)
- add_definitions(-DWITH_OPENAL)
- list(APPEND INC
- OpenAL
- )
- list(APPEND INC_SYS
- ${OPENAL_INCLUDE_DIR}
- )
- list(APPEND SRC
- OpenAL/AUD_OpenALDevice.cpp
-
- OpenAL/AUD_OpenALDevice.h
- )
-endif()
-
-if(WITH_JACK)
- add_definitions(-DWITH_JACK)
- list(APPEND INC
- jack
- )
- list(APPEND INC_SYS
- ${JACK_INCLUDE_DIRS}
- )
- list(APPEND SRC
- jack/AUD_JackDevice.cpp
- jack/AUD_JackLibrary.cpp
-
- jack/AUD_JackDevice.h
- jack/AUD_JackLibrary.h
- )
-
- if(WITH_JACK_DYNLOAD)
- add_definitions(-DWITH_JACK_DYNLOAD)
- endif()
-endif()
-
-if(WITH_CODEC_SNDFILE)
- add_definitions(-DWITH_SNDFILE)
- list(APPEND INC
- sndfile
- )
- list(APPEND INC_SYS
- ${SNDFILE_INCLUDE_DIRS}
- )
- list(APPEND SRC
- sndfile/AUD_SndFileFactory.cpp
- sndfile/AUD_SndFileReader.cpp
- sndfile/AUD_SndFileWriter.cpp
-
- sndfile/AUD_SndFileFactory.h
- sndfile/AUD_SndFileReader.h
- sndfile/AUD_SndFileWriter.h
- )
-endif()
-
-if(WITH_FFTW3 AND FALSE)
- add_definitions(-DWITH_FFTW3)
- list(APPEND INC
- fftw
- )
- list(APPEND INC_SYS
- ${FFTW3_INCLUDE_DIRS}
- )
- list(APPEND SRC
- fftw/AUD_BandPassFactory.cpp
- fftw/AUD_BandPassReader.cpp
-
- fftw/AUD_BandPassFactory.h
- fftw/AUD_BandPassReader.h
- )
-endif()
-
-if(WITH_PYTHON)
- list(APPEND INC
- Python
- )
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND SRC
- Python/AUD_PyAPI.cpp
-
- Python/AUD_PyAPI.h
- )
- add_definitions(-DWITH_PYTHON)
-endif()
-endif()
-
blender_add_lib(bf_intern_audaspace "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/audaspace/COPYING b/intern/audaspace/COPYING
deleted file mode 100644
index a330e6d9193..00000000000
--- a/intern/audaspace/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <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 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
deleted file mode 100644
index 00d3a9f2395..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_AccumulatorFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_AccumulatorFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-sample_t AUD_AccumulatorFactory::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 AUD_AccumulatorFactory::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(boost::shared_ptr<AUD_IFactory> factory,
- bool additive) :
- AUD_EffectFactory(factory),
- m_additive(additive)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_AccumulatorFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(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
deleted file mode 100644
index 9087218a5f9..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_AccumulatorFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_ACCUMULATORFACTORY_H__
-#define __AUD_ACCUMULATORFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * This factory creates an accumulator reader.
- *
- * The accumulator adds the difference at the input to the last output in case
- * it's positive. In additive mode it additionaly adds the difference always.
- * So in case the difference is positive, it's added twice.
- */
-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(boost::shared_ptr<AUD_IFactory> factory, bool additive = false);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless);
- static sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
-};
-
-#endif //__AUD_ACCUMULATORFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.cpp b/intern/audaspace/FX/AUD_BandpassCalculator.cpp
deleted file mode 100644
index f5bbd63f81c..00000000000
--- a/intern/audaspace/FX/AUD_BandpassCalculator.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "AUD_BandpassCalculator.h"
-
-AUD_BandpassCalculator::AUD_BandpassCalculator()
-{
-}
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.h b/intern/audaspace/FX/AUD_BandpassCalculator.h
deleted file mode 100644
index b5b3cad17ca..00000000000
--- a/intern/audaspace/FX/AUD_BandpassCalculator.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef AUD_BANDPASSCALCULATOR_H
-#define AUD_BANDPASSCALCULATOR_H
-
-class AUD_BandpassCalculator
-{
-public:
- AUD_BandpassCalculator();
-};
-
-#endif // AUD_BANDPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
deleted file mode 100644
index eadfc525f96..00000000000
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_BaseIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_BaseIIRFilterReader.h"
-
-#include <cstring>
-
-#define CC m_specs.channels + m_channel
-
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in,
- int out) :
- AUD_EffectReader(reader),
- m_specs(reader->getSpecs()),
- m_xlen(in), m_ylen(out),
- m_xpos(0), m_ypos(0), m_channel(0)
-{
- m_x = new sample_t[m_xlen * m_specs.channels];
- m_y = new sample_t[m_ylen * m_specs.channels];
-
- memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
- memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
-}
-
-AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
-{
- delete[] m_x;
- delete[] m_y;
-}
-
-void AUD_BaseIIRFilterReader::setLengths(int in, int out)
-{
- if(in != m_xlen)
- {
- sample_t* xn = new sample_t[in * m_specs.channels];
- memset(xn, 0, sizeof(sample_t) * in * m_specs.channels);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 1; i <= in && i <= m_xlen; i++)
- {
- xn[(in - i) * CC] = x(-i);
- }
- }
-
- delete[] m_x;
- m_x = xn;
- m_xpos = 0;
- m_xlen = in;
- }
-
- if(out != m_ylen)
- {
- sample_t* yn = new sample_t[out * m_specs.channels];
- memset(yn, 0, sizeof(sample_t) * out * m_specs.channels);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 1; i <= out && i <= m_ylen; i++)
- {
- yn[(out - i) * CC] = y(-i);
- }
- }
-
- delete[] m_y;
- m_y = yn;
- m_ypos = 0;
- m_ylen = out;
- }
-}
-
-void AUD_BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
- if(specs.channels != m_specs.channels)
- {
- m_specs.channels = specs.channels;
-
- delete[] m_x;
- delete[] m_y;
-
- m_x = new sample_t[m_xlen * m_specs.channels];
- m_y = new sample_t[m_ylen * m_specs.channels];
-
- memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
- memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
- }
-
- if(specs.rate != m_specs.rate)
- {
- m_specs = specs;
- sampleRateChanged(m_specs.rate);
- }
-
- m_reader->read(length, eos, buffer);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 0; i < length; i++)
- {
- m_x[m_xpos * CC] = buffer[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;
- }
- }
-}
-
-void AUD_BaseIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
-{
-}
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.cpp b/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
deleted file mode 100644
index 7a3c6f71e15..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "AUD_ButterworthCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define BWPB41 0.76536686473
-#define BWPB42 1.84775906502
-
-AUD_ButterworthCalculator::AUD_ButterworthCalculator(float frequency) :
- m_frequency(frequency)
-{
-}
-
-void AUD_ButterworthCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
-{
- float omega = 2 * tan(m_frequency * M_PI / rate);
- float o2 = omega * omega;
- float o4 = o2 * o2;
- float x1 = o2 + 2.0f * (float)BWPB41 * omega + 4.0f;
- float x2 = o2 + 2.0f * (float)BWPB42 * omega + 4.0f;
- float y1 = o2 - 2.0f * (float)BWPB41 * omega + 4.0f;
- float y2 = o2 - 2.0f * (float)BWPB42 * omega + 4.0f;
- float o228 = 2.0f * o2 - 8.0f;
- float norm = x1 * x2;
- 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]);
-}
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.h b/intern/audaspace/FX/AUD_ButterworthCalculator.h
deleted file mode 100644
index a7ae196afda..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthCalculator.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef AUD_BUTTERWORTHCALCULATOR_H
-#define AUD_BUTTERWORTHCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_ButterworthCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The attack value in seconds.
- */
- const float m_frequency;
-
-public:
- AUD_ButterworthCalculator(float frequency);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_BUTTERWORTHCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
deleted file mode 100644
index 12c4306c2f7..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ButterworthFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_ButterworthFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_ButterworthCalculator.h"
-
-AUD_ButterworthFactory::AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory,
- float frequency) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_ButterworthCalculator(frequency)))
-{
-}
-
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
deleted file mode 100644
index 3a86b14a7a6..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ButterworthFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_BUTTERWORTHFACTORY_H__
-#define __AUD_BUTTERWORTHFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a butterworth lowpass filter reader.
- */
-class AUD_ButterworthFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // 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(boost::shared_ptr<AUD_IFactory> factory, float frequency);
-};
-
-#endif //__AUD_BUTTERWORTHFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
deleted file mode 100644
index b5157d47666..00000000000
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_CallbackIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_CallbackIIRFilterReader.h"
-
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(boost::shared_ptr<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
deleted file mode 100644
index 66f82ba1a01..00000000000
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_CallbackIIRFilterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_CALLBACKIIRFILTERREADER_H__
-#define __AUD_CALLBACKIIRFILTERREADER_H__
-
-#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(boost::shared_ptr<AUD_IReader> reader, int in, int out,
- doFilterIIR doFilter,
- endFilterIIR endFilter = 0,
- void* data = NULL);
-
- virtual ~AUD_CallbackIIRFilterReader();
-
- virtual sample_t filter();
-};
-
-#endif //__AUD_CALLBACKIIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
deleted file mode 100644
index 3e5a7cfd2f8..00000000000
--- a/intern/audaspace/FX/AUD_DelayFactory.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DelayFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DelayFactory.h"
-#include "AUD_DelayReader.h"
-#include "AUD_Space.h"
-
-AUD_DelayFactory::AUD_DelayFactory(boost::shared_ptr<AUD_IFactory> factory, float delay) :
- AUD_EffectFactory(factory),
- m_delay(delay)
-{
-}
-
-float AUD_DelayFactory::getDelay() const
-{
- return m_delay;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DelayFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_DelayReader(getReader(), m_delay));
-}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
deleted file mode 100644
index 8cfb2be9ac8..00000000000
--- a/intern/audaspace/FX/AUD_DelayFactory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DelayFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DELAYFACTORY_H__
-#define __AUD_DELAYFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory, float delay = 0);
-
- /**
- * Returns the delay in seconds.
- */
- float getDelay() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_DELAYFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
deleted file mode 100644
index 050508f28da..00000000000
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DelayReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DelayReader.h"
-
-#include <cstring>
-
-AUD_DelayReader::AUD_DelayReader(boost::shared_ptr<AUD_IReader> reader, float delay) :
- AUD_EffectReader(reader),
- m_delay(int((AUD_SampleRate)delay * reader->getSpecs().rate)),
- m_remdelay(int((AUD_SampleRate)delay * reader->getSpecs().rate))
-{
-}
-
-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, bool& eos, sample_t* buffer)
-{
- if(m_remdelay > 0)
- {
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- if(length > m_remdelay)
- {
- memset(buffer, 0, m_remdelay * samplesize);
-
- int len = length - m_remdelay;
- m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
-
- length = m_remdelay + len;
-
- m_remdelay = 0;
- }
- else
- {
- memset(buffer, 0, length * samplesize);
- m_remdelay -= length;
- }
- }
- else
- m_reader->read(length, eos, buffer);
-}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
deleted file mode 100644
index d4388e3befc..00000000000
--- a/intern/audaspace/FX/AUD_DelayReader.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DelayReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DELAYREADER_H__
-#define __AUD_DELAYREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader and delays it.
- */
-class AUD_DelayReader : public AUD_EffectReader
-{
-private:
- /**
- * The delay level.
- */
- const int m_delay;
-
- /**
- * The remaining delay for playback.
- */
- int m_remdelay;
-
- // 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(boost::shared_ptr<AUD_IReader> reader, float delay);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_DELAYREADER_H__
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
deleted file mode 100644
index 21bcbc2f649..00000000000
--- a/intern/audaspace/FX/AUD_DoubleFactory.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DoubleFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DoubleFactory.h"
-#include "AUD_DoubleReader.h"
-
-AUD_DoubleFactory::AUD_DoubleFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
- m_factory1(factory1), m_factory2(factory2)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DoubleFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
- boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
-
- return boost::shared_ptr<AUD_IReader>(new AUD_DoubleReader(reader1, reader2));
-}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
deleted file mode 100644
index 4a02cc7bcdb..00000000000
--- a/intern/audaspace/FX/AUD_DoubleFactory.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DoubleFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DOUBLEFACTORY_H__
-#define __AUD_DOUBLEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory plays two other factories behind each other.
- */
-class AUD_DoubleFactory : public AUD_IFactory
-{
-private:
- /**
- * First played factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory1;
-
- /**
- * Second played factory.
- */
- boost::shared_ptr<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(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_DOUBLEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
deleted file mode 100644
index ee18914e93f..00000000000
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DoubleReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DoubleReader.h"
-
-#include <cstring>
-
-AUD_DoubleReader::AUD_DoubleReader(boost::shared_ptr<AUD_IReader> reader1,
- boost::shared_ptr<AUD_IReader> reader2) :
- m_reader1(reader1), m_reader2(reader2), m_finished1(false)
-{
- AUD_Specs s1, s2;
- s1 = reader1->getSpecs();
- s2 = reader2->getSpecs();
-}
-
-AUD_DoubleReader::~AUD_DoubleReader()
-{
-}
-
-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_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
-}
-
-void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- eos = false;
-
- if(!m_finished1)
- {
- int len = length;
-
- m_reader1->read(len, m_finished1, buffer);
-
- if(len < length)
- {
- AUD_Specs specs1, specs2;
- specs1 = m_reader1->getSpecs();
- specs2 = m_reader2->getSpecs();
- if(AUD_COMPARE_SPECS(specs1, specs2))
- {
- int len2 = length - len;
- m_reader2->read(len2, eos, buffer + specs1.channels * len);
- length = len + len2;
- }
- else
- length = len;
- }
- }
- else
- {
- m_reader2->read(length, eos, buffer);
- }
-}
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
deleted file mode 100644
index 5d2f65f1a90..00000000000
--- a/intern/audaspace/FX/AUD_DoubleReader.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DoubleReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DOUBLEREADER_H__
-#define __AUD_DOUBLEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This reader plays two readers sequently.
- */
-class AUD_DoubleReader : public AUD_IReader
-{
-private:
- /**
- * The first reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader1;
-
- /**
- * The second reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader2;
-
- /**
- * Whether we've reached the end of the first reader.
- */
- bool m_finished1;
-
- // hide copy constructor and operator=
- AUD_DoubleReader(const AUD_DoubleReader&);
- AUD_DoubleReader& operator=(const AUD_DoubleReader&);
-
-public:
- /**
- * Creates a new double reader.
- * \param reader1 The first reader to read from.
- * \param reader2 The second reader to read from.
- */
- AUD_DoubleReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_DOUBLEREADER_H__
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
deleted file mode 100644
index 319a78cfedd..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
- * \ingroup audfx
- */
-
-#include "AUD_DynamicIIRFilterFactory.h"
-#include "AUD_DynamicIIRFilterReader.h"
-
-
-AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator) :
- AUD_EffectFactory(factory),
- m_calculator(calculator)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_DynamicIIRFilterReader(getReader(), m_calculator));
-}
-
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
deleted file mode 100644
index aece7a8c2ef..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.h
- * \ingroup audfx
- */
-
-#ifndef __AUD_DYNAMICIIRFILTERFACTORY_H__
-#define __AUD_DYNAMICIIRFILTERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IDynamicIIRFilterCalculator.h"
-#include <vector>
-
-/**
- * This factory creates a IIR filter reader.
- *
- * This means that on sample rate change the filter recalculates its
- * coefficients.
- */
-class AUD_DynamicIIRFilterFactory : public AUD_EffectFactory
-{
-protected:
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> m_calculator;
-
-public:
- /**
- * Creates a new Dynmic IIR filter factory.
- * \param factory The input factory.
- */
- AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif // __AUD_DYNAMICIIRFILTERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
deleted file mode 100644
index 52aaf2311c0..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DynamicIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-#include "AUD_DynamicIIRFilterReader.h"
-
-AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator) :
- AUD_IIRFilterReader(reader, std::vector<float>(), std::vector<float>()),
- m_calculator(calculator)
-{
- sampleRateChanged(reader->getSpecs().rate);
-}
-
-void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
-{
- std::vector<float> a, b;
- m_calculator->recalculateCoefficients(rate, b, a);
- setCoefficients(b, a);
-}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
deleted file mode 100644
index 0b68578bc53..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_DynamicIIRFilterReader.h
- * \ingroup audfx
- */
-
-#ifndef __AUD_DYNAMICIIRFILTERREADER_H__
-#define __AUD_DYNAMICIIRFILTERREADER_H__
-
-#include "AUD_IIRFilterReader.h"
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-/**
- * This class is for dynamic infinite impulse response filters with simple
- * coefficients that change depending on the sample rate.
- */
-class AUD_DynamicIIRFilterReader : public AUD_IIRFilterReader
-{
-private:
- /**
- * The factory for dynamically recalculating filter coefficients.
- */
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> m_calculator;
-
-public:
- AUD_DynamicIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
-
- virtual void sampleRateChanged(AUD_SampleRate rate);
-};
-
-#endif // __AUD_DYNAMICIIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
deleted file mode 100644
index 6018ed561ca..00000000000
--- a/intern/audaspace/FX/AUD_EffectFactory.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EffectFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IReader.h"
-
-AUD_EffectFactory::AUD_EffectFactory(boost::shared_ptr<AUD_IFactory> factory)
-{
- m_factory = factory;
-}
-
-AUD_EffectFactory::~AUD_EffectFactory()
-{
-}
-
-boost::shared_ptr<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
deleted file mode 100644
index d09872638be..00000000000
--- a/intern/audaspace/FX/AUD_EffectFactory.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EffectFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_EFFECTFACTORY_H__
-#define __AUD_EFFECTFACTORY_H__
-
-#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.
- */
- boost::shared_ptr<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 boost::shared_ptr<AUD_IReader> getReader() const
- {
- return m_factory->createReader();
- }
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- */
- AUD_EffectFactory(boost::shared_ptr<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.
- */
- boost::shared_ptr<AUD_IFactory> getFactory() const;
-};
-
-#endif //__AUD_EFFECTFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
deleted file mode 100644
index b3e80bef03b..00000000000
--- a/intern/audaspace/FX/AUD_EffectReader.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EffectReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EffectReader.h"
-
-AUD_EffectReader::AUD_EffectReader(boost::shared_ptr<AUD_IReader> reader)
-{
- m_reader = reader;
-}
-
-AUD_EffectReader::~AUD_EffectReader()
-{
-}
-
-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, bool& eos, sample_t* buffer)
-{
- m_reader->read(length, eos, buffer);
-}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
deleted file mode 100644
index 2745c12afaf..00000000000
--- a/intern/audaspace/FX/AUD_EffectReader.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EffectReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_EFFECTREADER_H__
-#define __AUD_EFFECTREADER_H__
-
-#include "AUD_IReader.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * 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.
- */
- boost::shared_ptr<AUD_IReader> m_reader;
-
-public:
- /**
- * Creates a new effect reader.
- * \param reader The reader to read from.
- */
- AUD_EffectReader(boost::shared_ptr<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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_EFFECTREADER_H__
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
deleted file mode 100644
index 1e5737557c1..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EnvelopeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EnvelopeFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-#include <cmath>
-
-struct EnvelopeParameters
-{
- float attack;
- float release;
- float threshold;
- float arthreshold;
-};
-
-sample_t AUD_EnvelopeFactory::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 AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
-{
- delete param;
-}
-
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(boost::shared_ptr<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)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_EnvelopeFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
-
- EnvelopeParameters* param = new EnvelopeParameters();
- param->arthreshold = m_arthreshold;
- param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
- param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
- param->threshold = m_threshold;
-
- return boost::shared_ptr<AUD_IReader>(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
deleted file mode 100644
index 656212c8cac..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_EnvelopeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_ENVELOPEFACTORY_H__
-#define __AUD_ENVELOPEFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-struct EnvelopeParameters;
-
-/**
- * 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(boost::shared_ptr<AUD_IFactory> factory, float attack, float release,
- float threshold, float arthreshold);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param);
- static void endEnvelopeFilter(EnvelopeParameters* param);
-};
-
-#endif //__AUD_ENVELOPEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
deleted file mode 100644
index b34d2134385..00000000000
--- a/intern/audaspace/FX/AUD_FaderFactory.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_FaderFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_FaderFactory.h"
-#include "AUD_FaderReader.h"
-
-AUD_FaderFactory::AUD_FaderFactory(boost::shared_ptr<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;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_FaderFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(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
deleted file mode 100644
index f9ad88a751d..00000000000
--- a/intern/audaspace/FX/AUD_FaderFactory.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_FaderFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_FADERFACTORY_H__
-#define __AUD_FADERFACTORY_H__
-
-#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(boost::shared_ptr<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 boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_FADERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
deleted file mode 100644
index e09072054cb..00000000000
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_FaderReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_FaderReader.h"
-
-#include <cstring>
-
-AUD_FaderReader::AUD_FaderReader(boost::shared_ptr<AUD_IReader> reader, AUD_FadeType type,
- float start,float length) :
- AUD_EffectReader(reader),
- m_type(type),
- m_start(start),
- m_length(length)
-{
-}
-
-void AUD_FaderReader::read(int& length, bool& eos, sample_t* buffer)
-{
- int position = m_reader->getPosition();
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_reader->read(length, eos, buffer);
-
- if((position + length) / (float)specs.rate <= m_start)
- {
- if(m_type != AUD_FADE_OUT)
- {
- memset(buffer, 0, length * samplesize);
- }
- }
- else if(position / (float)specs.rate >= m_start+m_length)
- {
- if(m_type == AUD_FADE_OUT)
- {
- memset(buffer, 0, length * samplesize);
- }
- }
- else
- {
- 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;
- }
-
- buffer[i] = buffer[i] * volume;
- }
- }
-}
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
deleted file mode 100644
index a49960b30fb..00000000000
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_FaderReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_FADERREADER_H__
-#define __AUD_FADERREADER_H__
-
-#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;
-
- // 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(boost::shared_ptr<AUD_IReader> reader, AUD_FadeType type,
- float start,float length);
-
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_FADERREADER_H__
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.cpp b/intern/audaspace/FX/AUD_HighpassCalculator.cpp
deleted file mode 100644
index 573bba1c62b..00000000000
--- a/intern/audaspace/FX/AUD_HighpassCalculator.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "AUD_HighpassCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_HighpassCalculator::AUD_HighpassCalculator(float frequency, float Q) :
- m_frequency(frequency),
- m_Q(Q)
-{
-}
-
-void AUD_HighpassCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
-{
- float w0 = 2.0 * M_PI * (AUD_SampleRate)m_frequency / rate;
- float alpha = (float)(sin(w0) / (2.0 * (double)m_Q));
- float norm = 1 + alpha;
- float c = cos(w0);
- 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]);
-}
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.h b/intern/audaspace/FX/AUD_HighpassCalculator.h
deleted file mode 100644
index bad1c08f7c7..00000000000
--- a/intern/audaspace/FX/AUD_HighpassCalculator.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef AUD_HIGHPASSCALCULATOR_H
-#define AUD_HIGHPASSCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_HighpassCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
-public:
- AUD_HighpassCalculator(float frequency, float Q);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_HIGHPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
deleted file mode 100644
index 2456085a8a1..00000000000
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_HighpassFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_HighpassFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_HighpassCalculator.h"
-
-AUD_HighpassFactory::AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
- float Q) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_HighpassCalculator(frequency, Q)))
-{
-}
-
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
deleted file mode 100644
index 56ced91c53c..00000000000
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_HighpassFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_HIGHPASSFACTORY_H__
-#define __AUD_HIGHPASSFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a highpass filter reader.
- */
-class AUD_HighpassFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // 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(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-};
-
-#endif //__AUD_HIGHPASSFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
deleted file mode 100644
index 2e0d8418571..00000000000
--- a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
- * \ingroup audfx
- */
-
-#ifndef AUD_IDYNAMICIIRFILTERCALCULATOR_H
-#define AUD_IDYNAMICIIRFILTERCALCULATOR_H
-
-#include "AUD_Space.h"
-
-#include <vector>
-
-/**
- * This interface calculates dynamic filter coefficients which depend on the
- * sampling rate for AUD_DynamicIIRFilterReaders.
- */
-class AUD_IDynamicIIRFilterCalculator
-{
-public:
- virtual ~AUD_IDynamicIIRFilterCalculator() {}
-
- /**
- * Recalculates the filter coefficients.
- * \param rate The sample rate of the audio data.
- * \param[out] b The input filter coefficients.
- * \param[out] a The output filter coefficients.
- */
- virtual void recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float>& b,
- std::vector<float>& a)=0;
-};
-
-#endif // AUD_IDYNAMICIIRFILTERCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
deleted file mode 100644
index c4f94a2dc27..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_IIRFilterFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_IIRFilterFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-AUD_IIRFilterFactory::AUD_IIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
- std::vector<float> b,
- std::vector<float> a) :
- AUD_EffectFactory(factory), m_a(a), m_b(b)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_IIRFilterFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), m_b, m_a));
-}
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
deleted file mode 100644
index 0b55c120384..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_IIRFilterFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_IIRFILTERFACTORY_H__
-#define __AUD_IIRFILTERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IDynamicIIRFilterCalculator.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(boost::shared_ptr<AUD_IFactory> factory, std::vector<float> b,
- std::vector<float> a);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_IIRFILTERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
deleted file mode 100644
index 6716e6b9ddc..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterReader.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_IIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_IIRFilterReader.h"
-
-AUD_IIRFilterReader::AUD_IIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
- const std::vector<float>& b,
- const std::vector<float>& a) :
- AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
-{
- if(m_a.empty() == false)
- {
- 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;
-}
-
-void AUD_IIRFilterReader::setCoefficients(const std::vector<float>& b,
- const std::vector<float>& a)
-{
- setLengths(b.size(), a.size());
- m_a = a;
- m_b = b;
-}
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
deleted file mode 100644
index d663805b50f..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterReader.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_IIRFilterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_IIRFILTERREADER_H__
-#define __AUD_IIRFILTERREADER_H__
-
-#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(boost::shared_ptr<AUD_IReader> reader, const std::vector<float>& b,
- const std::vector<float>& a);
-
- virtual sample_t filter();
-
- void setCoefficients(const std::vector<float>& b,
- const std::vector<float>& a);
-};
-
-#endif //__AUD_IIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
deleted file mode 100644
index 679ed3a6b8b..00000000000
--- a/intern/audaspace/FX/AUD_LimiterFactory.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LimiterFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LimiterFactory.h"
-#include "AUD_LimiterReader.h"
-#include "AUD_Space.h"
-
-AUD_LimiterFactory::AUD_LimiterFactory(boost::shared_ptr<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;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LimiterFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_LimiterReader(getReader(), m_start, m_end));
-}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
deleted file mode 100644
index 0376952b4bd..00000000000
--- a/intern/audaspace/FX/AUD_LimiterFactory.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LimiterFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LIMITERFACTORY_H__
-#define __AUD_LIMITERFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory,
- float start = 0, float end = -1);
-
- /**
- * Returns the start time.
- */
- float getStart() const;
-
- /**
- * Returns the end time.
- */
- float getEnd() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_LIMITERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
deleted file mode 100644
index 607eb9e5bec..00000000000
--- a/intern/audaspace/FX/AUD_LimiterReader.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LimiterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LIMITERREADER_H__
-#define __AUD_LIMITERREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This reader limits another reader in start and end times.
- */
-class AUD_LimiterReader : public AUD_EffectReader
-{
-private:
- /**
- * The start sample: inclusive.
- */
- const float m_start;
-
- /**
- * The end sample: exlusive.
- */
- const float 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 time (inclusive).
- * \param end The desired end time (sample exklusive), a negative value
- * signals that it should play to the end.
- */
- AUD_LimiterReader(boost::shared_ptr<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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LIMITERREADER_H__
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
deleted file mode 100644
index a9e83e349a0..00000000000
--- a/intern/audaspace/FX/AUD_LoopFactory.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LoopFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LoopFactory.h"
-#include "AUD_LoopReader.h"
-
-AUD_LoopFactory::AUD_LoopFactory(boost::shared_ptr<AUD_IFactory> factory, int loop) :
- AUD_EffectFactory(factory),
- m_loop(loop)
-{
-}
-
-int AUD_LoopFactory::getLoop() const
-{
- return m_loop;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LoopFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_LoopReader(getReader(), m_loop));
-}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
deleted file mode 100644
index 570536bee9a..00000000000
--- a/intern/audaspace/FX/AUD_LoopFactory.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LoopFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOOPFACTORY_H__
-#define __AUD_LOOPFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory, int loop = -1);
-
- /**
- * Returns the loop count.
- */
- int getLoop() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_LOOPFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
deleted file mode 100644
index 6fbcaa5af37..00000000000
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LoopReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LoopReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-AUD_LoopReader::AUD_LoopReader(boost::shared_ptr<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, bool& eos, sample_t* buffer)
-{
- const AUD_Specs specs = m_reader->getSpecs();
-
- int len = length;
-
- m_reader->read(length, eos, buffer);
-
- if(length < len && eos && m_left)
- {
- int pos = length;
- length = len;
-
- while(pos < length && eos && m_left)
- {
- if(m_left > 0)
- m_left--;
-
- m_reader->seek(0);
-
- len = length - pos;
- m_reader->read(len, eos, buffer + pos * specs.channels);
-
- // prevent endless loop
- if(!len)
- break;
-
- pos += len;
- }
-
- length = pos;
- }
-}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
deleted file mode 100644
index 12b8078b12d..00000000000
--- a/intern/audaspace/FX/AUD_LoopReader.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LoopReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOOPREADER_H__
-#define __AUD_LOOPREADER_H__
-
-#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 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(boost::shared_ptr<AUD_IReader> reader, int loop);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LOOPREADER_H__
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.cpp b/intern/audaspace/FX/AUD_LowpassCalculator.cpp
deleted file mode 100644
index 57452f09038..00000000000
--- a/intern/audaspace/FX/AUD_LowpassCalculator.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "AUD_LowpassCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_LowpassCalculator::AUD_LowpassCalculator(float frequency, float Q) :
- m_frequency(frequency),
- m_Q(Q)
-{
-}
-
-void AUD_LowpassCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
-{
- float w0 = 2 * M_PI * m_frequency / rate;
- float alpha = sin(w0) / (2 * m_Q);
- float norm = 1 + alpha;
- float c = cos(w0);
- 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]);
-}
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.h b/intern/audaspace/FX/AUD_LowpassCalculator.h
deleted file mode 100644
index 18bb11feda7..00000000000
--- a/intern/audaspace/FX/AUD_LowpassCalculator.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef AUD_LOWPASSCALCULATOR_H
-#define AUD_LOWPASSCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_LowpassCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
-public:
- AUD_LowpassCalculator(float frequency, float Q);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_LOWPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
deleted file mode 100644
index bd225998392..00000000000
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LowpassFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LowpassFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_LowpassCalculator.h"
-
-AUD_LowpassFactory::AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
- float Q) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_LowpassCalculator(frequency, Q)))
-{
-}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
deleted file mode 100644
index dfd8ab35521..00000000000
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_LowpassFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOWPASSFACTORY_H__
-#define __AUD_LOWPASSFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a lowpass filter reader.
- */
-class AUD_LowpassFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // 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(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-};
-
-#endif //__AUD_LOWPASSFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
deleted file mode 100644
index 84e4b29415e..00000000000
--- a/intern/audaspace/FX/AUD_PingPongFactory.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PingPongFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PingPongFactory.h"
-#include "AUD_DoubleReader.h"
-#include "AUD_ReverseFactory.h"
-
-AUD_PingPongFactory::AUD_PingPongFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_PingPongFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
- AUD_ReverseFactory factory(m_factory);
- boost::shared_ptr<AUD_IReader> reader2 = factory.createReader();
-
- return boost::shared_ptr<AUD_IReader>(new AUD_DoubleReader(reader, reader2));
-}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
deleted file mode 100644
index e8ee5c9e389..00000000000
--- a/intern/audaspace/FX/AUD_PingPongFactory.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PingPongFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PINGPONGFACTORY_H__
-#define __AUD_PINGPONGFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory plays another factory first normal, then reversed.
- * \note Readers from the underlying factory must be reversable with seeking.
- */
-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(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_PINGPONGFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
deleted file mode 100644
index 9dc27a58162..00000000000
--- a/intern/audaspace/FX/AUD_PitchFactory.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PitchFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PitchFactory.h"
-#include "AUD_PitchReader.h"
-#include "AUD_Space.h"
-
-AUD_PitchFactory::AUD_PitchFactory(boost::shared_ptr<AUD_IFactory> factory, float pitch) :
- AUD_EffectFactory(factory),
- m_pitch(pitch)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_PitchFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_PitchReader(getReader(), m_pitch));
-}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
deleted file mode 100644
index 159388b28dd..00000000000
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PitchFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PITCHFACTORY_H__
-#define __AUD_PITCHFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory, float pitch);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_PITCHFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
deleted file mode 100644
index b3775c71a28..00000000000
--- a/intern/audaspace/FX/AUD_PitchReader.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PitchReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PitchReader.h"
-
-AUD_PitchReader::AUD_PitchReader(boost::shared_ptr<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 *= m_pitch;
- return specs;
-}
-
-float AUD_PitchReader::getPitch() const
-{
- return m_pitch;
-}
-
-void AUD_PitchReader::setPitch(float pitch)
-{
- if(pitch <= 0)
- pitch = 1;
- m_pitch = pitch;
-}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
deleted file mode 100644
index d22e589b05d..00000000000
--- a/intern/audaspace/FX/AUD_PitchReader.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_PitchReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PITCHREADER_H__
-#define __AUD_PITCHREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This class reads another reader and changes it's pitch.
- */
-class AUD_PitchReader : public AUD_EffectReader
-{
-private:
- /**
- * The pitch level.
- */
- 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 pitch value.
- */
- AUD_PitchReader(boost::shared_ptr<AUD_IReader> reader, float pitch);
-
- virtual AUD_Specs getSpecs() const;
-
- /**
- * Retrieves the pitch.
- * \return The current pitch value.
- */
- float getPitch() const;
-
- /**
- * Sets the pitch.
- * \param pitch The new pitch value.
- */
- void setPitch(float pitch);
-};
-
-#endif //__AUD_PITCHREADER_H__
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
deleted file mode 100644
index 26bb5615dad..00000000000
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_RectifyFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_RectifyFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-#include <cmath>
-
-sample_t AUD_RectifyFactory::rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
-{
- return fabs(reader->x(0));
-}
-
-AUD_RectifyFactory::AUD_RectifyFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_RectifyFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter));
-}
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h
deleted file mode 100644
index eb595e43e4f..00000000000
--- a/intern/audaspace/FX/AUD_RectifyFactory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_RectifyFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_RECTIFYFACTORY_H__
-#define __AUD_RECTIFYFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * 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(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
-};
-
-#endif //__AUD_RECTIFYFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
deleted file mode 100644
index afb4ad2bec9..00000000000
--- a/intern/audaspace/FX/AUD_ReverseFactory.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ReverseFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_ReverseFactory.h"
-#include "AUD_ReverseReader.h"
-#include "AUD_Space.h"
-
-AUD_ReverseFactory::AUD_ReverseFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ReverseFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_ReverseReader(getReader()));
-}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
deleted file mode 100644
index 5b0c9e3c29a..00000000000
--- a/intern/audaspace/FX/AUD_ReverseFactory.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ReverseFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_REVERSEFACTORY_H__
-#define __AUD_REVERSEFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory reads another factory reverted.
- * \note Readers from the underlying factory must be seekable.
- */
-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(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_REVERSEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
deleted file mode 100644
index c0a5962a299..00000000000
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ReverseReader.cpp
- * \ingroup audfx
- */
-
-
-#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(boost::shared_ptr<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, bool& eos, sample_t* buffer)
-{
- // first correct the length
- if(m_position + length > m_length)
- length = m_length - m_position;
-
- if(length <= 0)
- {
- length = 0;
- eos = true;
- return;
- }
-
- const AUD_Specs specs = getSpecs();
- const int samplesize = AUD_SAMPLE_SIZE(specs);
-
- sample_t temp[AUD_CHANNEL_MAX];
-
- int len = length;
-
- // read from reader
- m_reader->seek(m_length - m_position - len);
- m_reader->read(len, eos, buffer);
-
- // set null if reader didn't give enough data
- if(len < length)
- memset(buffer, 0, (length - len) * samplesize);
-
- // copy the samples reverted
- for(int i = 0; i < length / 2; i++)
- {
- memcpy(temp,
- buffer + (len - 1 - i) * specs.channels,
- samplesize);
- memcpy(buffer + (len - 1 - i) * specs.channels,
- buffer + i * specs.channels,
- samplesize);
- memcpy(buffer + i * specs.channels,
- temp,
- samplesize);
- }
-
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
deleted file mode 100644
index 219047915bd..00000000000
--- a/intern/audaspace/FX/AUD_ReverseReader.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_ReverseReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_REVERSEREADER_H__
-#define __AUD_REVERSEREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader from back to front.
- * \note The underlying reader must be seekable.
- */
-class AUD_ReverseReader : public AUD_EffectReader
-{
-private:
- /**
- * The sample count.
- */
- const int m_length;
-
- /**
- * The current position.
- */
- int m_position;
-
- // 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(boost::shared_ptr<AUD_IReader> reader);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_REVERSEREADER_H__
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
deleted file mode 100644
index 4b4dccb6e6b..00000000000
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SquareFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SquareFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-sample_t AUD_SquareFactory::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 AUD_SquareFactory::endSquareFilter(float* threshold)
-{
- delete threshold;
-}
-
-AUD_SquareFactory::AUD_SquareFactory(boost::shared_ptr<AUD_IFactory> factory, float threshold) :
- AUD_EffectFactory(factory),
- m_threshold(threshold)
-{
-}
-
-float AUD_SquareFactory::getThreshold() const
-{
- return m_threshold;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SquareFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(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
deleted file mode 100644
index 27e62b6f4cc..00000000000
--- a/intern/audaspace/FX/AUD_SquareFactory.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SquareFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SQUAREFACTORY_H__
-#define __AUD_SQUAREFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * 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(boost::shared_ptr<AUD_IFactory> factory, float threshold = 0.0f);
-
- /**
- * Returns the threshold.
- */
- float getThreshold() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold);
- static void endSquareFilter(float* threshold);
-};
-
-#endif //__AUD_SQUAREFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
deleted file mode 100644
index 7f82233a0b7..00000000000
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SumFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SumFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-AUD_SumFactory::AUD_SumFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SumFactory::createReader()
-{
- std::vector<float> a, b;
- a.push_back(1);
- a.push_back(-1);
- b.push_back(1);
- return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), b, a));
-}
diff --git a/intern/audaspace/FX/AUD_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
deleted file mode 100644
index a916f3509cb..00000000000
--- a/intern/audaspace/FX/AUD_SumFactory.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SumFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUMFACTORY_H__
-#define __AUD_SUMFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SUMFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
deleted file mode 100644
index 3efad37a5b3..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeFactory.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SuperposeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SuperposeFactory.h"
-#include "AUD_SuperposeReader.h"
-
-AUD_SuperposeFactory::AUD_SuperposeFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
- m_factory1(factory1), m_factory2(factory2)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SuperposeFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
- boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
-
- return boost::shared_ptr<AUD_IReader>(new AUD_SuperposeReader(reader1, reader2));
-}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
deleted file mode 100644
index caa0dfb752f..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeFactory.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SuperposeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUPERPOSEFACTORY_H__
-#define __AUD_SUPERPOSEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory mixes two other factories, playing them the same time.
- * \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.
- */
- boost::shared_ptr<AUD_IFactory> m_factory1;
-
- /**
- * Second played factory.
- */
- boost::shared_ptr<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(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SUPERPOSEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
deleted file mode 100644
index 294a48b3e7a..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeReader.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SuperposeReader.cpp
- * \ingroup audfx
- */
-
-
-#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(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2) :
- m_reader1(reader1), m_reader2(reader2)
-{
-}
-
-AUD_SuperposeReader::~AUD_SuperposeReader()
-{
-}
-
-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, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader1->getSpecs();
- AUD_Specs s2 = m_reader2->getSpecs();
- if(!AUD_COMPARE_SPECS(specs, s2))
- AUD_THROW(AUD_ERROR_SPECS, specs_error);
-
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_buffer.assureSize(length * samplesize);
-
- int len1 = length;
- m_reader1->read(len1, eos, buffer);
-
- if(len1 < length)
- memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
-
- int len2 = length;
- bool eos2;
- sample_t* buf = m_buffer.getBuffer();
- m_reader2->read(len2, eos2, buf);
-
- for(int i = 0; i < len2 * specs.channels; i++)
- buffer[i] += buf[i];
-
- length = AUD_MAX(len1, len2);
- eos &= eos2;
-}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
deleted file mode 100644
index a04ab90fe43..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeReader.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_SuperposeReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUPERPOSEREADER_H__
-#define __AUD_SUPERPOSEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This reader plays two readers with the same specs in parallel.
- */
-class AUD_SuperposeReader : public AUD_IReader
-{
-private:
- /**
- * The first reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader1;
-
- /**
- * The second reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader2;
-
- /**
- * Buffer used for mixing.
- */
- 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(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SUPERPOSEREADER_H__
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
deleted file mode 100644
index 4f0e1e425e6..00000000000
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_VolumeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_VolumeFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-AUD_VolumeFactory::AUD_VolumeFactory(boost::shared_ptr<AUD_IFactory> factory, float volume) :
- AUD_EffectFactory(factory),
- m_volume(volume)
-{
-}
-
-float AUD_VolumeFactory::getVolume() const
-{
- return m_volume;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_VolumeFactory::createReader()
-{
- std::vector<float> a, b;
- a.push_back(1);
- b.push_back(m_volume);
- return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), b, a));
-}
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
deleted file mode 100644
index 6fe779ffb88..00000000000
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/FX/AUD_VolumeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_VOLUMEFACTORY_H__
-#define __AUD_VOLUMEFACTORY_H__
-
-#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(boost::shared_ptr<AUD_IFactory> factory, float volume);
-
- /**
- * Returns the volume.
- * \return The current volume.
- */
- float getVolume() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_VOLUMEFACTORY_H__
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
deleted file mode 100644
index c0c77b6f917..00000000000
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ /dev/null
@@ -1,1647 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/OpenAL/AUD_OpenALDevice.cpp
- * \ingroup audopenal
- */
-
-
-#include "AUD_OpenALDevice.h"
-#include "AUD_IFactory.h"
-#include "AUD_IReader.h"
-#include "AUD_ConverterReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <limits>
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-/*struct AUD_OpenALBufferedFactory
-{
- /// The factory.
- AUD_IFactory* factory;
-
- /// The OpenAL buffer.
- ALuint buffer;
-};*/
-
-//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
-
-
-/******************************************************************************/
-/*********************** AUD_OpenALHandle Handle Code *************************/
-/******************************************************************************/
-
-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.";
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PLAYING)
- {
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
- m_device->m_pausedSounds.push_back(This);
-
- alSourcePause(m_source);
-
- m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
-
- return true;
- }
- }
- }
- }
-
- return false;}
-
-AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
- m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
- m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
- m_device(device)
-{
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
-
- // OpenAL playback code
- alGenBuffers(CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
- try
- {
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
- int length;
- bool eos;
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- reader->read(length, eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
- }
-
- alGenSources(1, &m_source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &m_source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
- throw;
- }
- alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
-{
- return pause(false);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PAUSED)
- {
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_pausedSounds.erase(it);
- m_device->m_playingSounds.push_back(This);
-
- m_device->start();
- m_status = AUD_STATUS_PLAYING;
-
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_status = AUD_STATUS_INVALID;
-
- alDeleteSources(1, &m_source);
- if(!m_isBuffered)
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
-
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
-
- return true;
- }
- }
-
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- m_device->m_pausedSounds.erase(it);
- return true;
- }
- }
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep()
-{
- if(m_status)
- return m_keep;
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_keep = keep;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- if(m_isBuffered)
- alSourcef(m_source, AL_SEC_OFFSET, position);
- else
- {
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
- m_eos = false;
-
- ALint info;
-
- alGetSourcei(m_source, AL_SOURCE_STATE, &info);
-
- // we need to stop playing sounds as well to clear the buffers
- // this might cause clicks, but fixes a bug regarding position determination
- if(info == AL_PAUSED || info == AL_PLAYING)
- alSourceStop(m_source);
-
- alSourcei(m_source, AL_BUFFER, 0);
- m_current = 0;
-
- ALenum err;
- if((err = alGetError()) == AL_NO_ERROR)
- {
- int length;
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
-
- if(alGetError() != AL_NO_ERROR)
- break;
- }
-
- if(m_loopcount != 0)
- m_eos = false;
-
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- }
-
- alSourceRewind(m_source);
- }
-
- if(m_status == AUD_STATUS_STOPPED)
- m_status = AUD_STATUS_PAUSED;
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return 0.0f;
-
- float position = 0.0f;
-
- alGetSourcef(m_source, AL_SEC_OFFSET, &position);
-
- if(!m_isBuffered)
- {
- int queued;
-
- // this usually always returns CYCLE_BUFFERS
- alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queued);
-
- AUD_Specs specs = m_reader->getSpecs();
- position += (m_reader->getPosition() - m_device->m_buffersize *
- queued) / (float)specs.rate;
- }
-
- return position;
-}
-
-AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus()
-{
- return m_status;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_PITCH, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_PITCH, pitch);
-
- return true;
-}
-
-int AUD_OpenALDevice::AUD_OpenALHandle::getLoopCount()
-{
- if(!m_status)
- return 0;
- return m_loopcount;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
-{
- if(!m_status)
- return false;
-
- if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
- m_status = AUD_STATUS_PAUSED;
-
- m_loopcount = count;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_stop = callback;
- m_stop_data = data;
-
- return true;
-}
-
-/******************************************************************************/
-/********************* AUD_OpenALHandle 3DHandle Code *************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat p[3];
- alGetSourcefv(m_source, AL_POSITION, p);
-
- result = AUD_Vector3(p[0], p[1], p[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& location)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
-
- return true;
-}
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat v[3];
- alGetSourcefv(m_source, AL_VELOCITY, v);
-
- result = AUD_Vector3(v[0], v[1], v[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& velocity)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
-
- return true;
-}
-
-AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
-{
- return m_orientation;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
-{
- 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;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_DIRECTION, direction);
-
- m_orientation = orientation;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
-{
- int result;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MIN_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MIN_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
-
- return true;
-}
-
-/******************************************************************************/
-/**************************** Threading Code **********************************/
-/******************************************************************************/
-
-static void *AUD_openalRunThread(void *device)
-{
- AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
- dev->updateStreams();
- return NULL;
-}
-
-void AUD_OpenALDevice::start(bool join)
-{
- AUD_MutexLock lock(*this);
-
- if(!m_playing)
- {
- if(join)
- pthread_join(m_thread, NULL);
-
- 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;
- }
-}
-
-void AUD_OpenALDevice::updateStreams()
-{
- boost::shared_ptr<AUD_OpenALHandle> sound;
-
- int length;
-
- ALint info;
- AUD_DeviceSpecs specs = m_specs;
- ALCenum cerr;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > stopSounds;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > pauseSounds;
- AUD_HandleIterator it;
-
- while(1)
- {
- lock();
-
- alcSuspendContext(m_context);
- cerr = alcGetError(m_device);
- if(cerr == ALC_NO_ERROR)
- {
- // for all sounds
- for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
- {
- sound = *it;
-
- // is it a streamed sound?
- if(!sound->m_isBuffered)
- {
- // check for buffer refilling
- alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
-
- if(info)
- {
- specs.specs = sound->m_reader->getSpecs();
- m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- // for all empty buffers
- while(info--)
- {
- // if there's still data to play back
- if(!sound->m_eos)
- {
- // read data
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
-
- // looping necessary?
- if(length == 0 && sound->m_loopcount)
- {
- if(sound->m_loopcount > 0)
- sound->m_loopcount--;
-
- sound->m_reader->seek(0);
-
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
- }
-
- if(sound->m_loopcount != 0)
- sound->m_eos = false;
-
- // read nothing?
- if(length == 0)
- {
- break;
- }
-
- // unqueue buffer (warning: this might fail for slow early returning sources (none exist so far) if the buffer was not queued due to recent changes - has to be tested)
- alSourceUnqueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]);
- ALenum err;
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // fill with new data
- alBufferData(sound->m_buffers[sound->m_current],
- sound->m_format,
- m_buffer.getBuffer(), length *
- AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
-
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // and queue again
- alSourceQueueBuffers(sound->m_source, 1,
- &sound->m_buffers[sound->m_current]);
- if(alGetError() != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- sound->m_current = (sound->m_current+1) %
- AUD_OpenALHandle::CYCLE_BUFFERS;
- }
- else
- break;
- }
- }
- }
-
- // check if the sound has been stopped
- alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
-
- if(info != AL_PLAYING)
- {
- // if it really stopped
- if(sound->m_eos && info != AL_INITIAL)
- {
- if(sound->m_stop)
- sound->m_stop(sound->m_stop_data);
-
- // pause or
- if(sound->m_keep)
- pauseSounds.push_back(sound);
- // stop
- else
- stopSounds.push_back(sound);
- }
- // continue playing
- else
- alSourcePlay(sound->m_source);
- }
- }
-
- for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- (*it)->pause(true);
-
- for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- (*it)->stop();
-
- pauseSounds.clear();
- stopSounds.clear();
-
- alcProcessContext(m_context);
- }
-
- // stop thread
- if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
- {
- m_playing = false;
- unlock();
- pthread_exit(NULL);
- }
-
- unlock();
-
-#ifdef WIN32
- Sleep(20);
-#else
- usleep(20000);
-#endif
- }
-}
-
-/******************************************************************************/
-/**************************** IDevice Code ************************************/
-/******************************************************************************/
-
-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.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, (ALCint)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;
-
- if((!m_useMC && specs.channels > AUD_CHANNELS_STEREO) ||
- specs.channels == AUD_CHANNELS_STEREO_LFE ||
- specs.channels == AUD_CHANNELS_SURROUND5)
- specs.channels = AUD_CHANNELS_STEREO;
-
- alGetError();
- alcGetError(m_device);
-
- m_specs = specs;
- m_buffersize = buffersize;
- m_playing = false;
-
-// 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);
-
- start(false);
-}
-
-AUD_OpenALDevice::~AUD_OpenALDevice()
-{
- lock();
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
-
- // 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
- unlock();
- pthread_join(m_thread, NULL);
-
- //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;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- AUD_Specs specs = reader->getSpecs();
-
- // check format
- if(specs.channels == AUD_CHANNELS_INVALID)
- return boost::shared_ptr<AUD_IHandle>();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
-
- ALenum format;
-
- if(!getFormat(format, specs))
- return boost::shared_ptr<AUD_IHandle>();
-
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle> sound;
-
- try
- {
- // create the handle
- sound = boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle>(new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep));
- }
- catch(AUD_Exception&)
- {
- alcProcessContext(m_context);
- throw;
- }
-
- alcProcessContext(m_context);
-
- // play sound
- m_playingSounds.push_back(sound);
-
- start();
-
- return boost::shared_ptr<AUD_IHandle>(sound);
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- /* AUD_XXX disabled
- AUD_OpenALHandle* sound = NULL;
-
- lock();
-
- 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->eos = 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;*/
-
- return play(factory->createReader(), keep);
-}
-
-void AUD_OpenALDevice::stopAll()
-{
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
- alcProcessContext(m_context);
-}
-
-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);
-}
-
-/* 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))
- {
- 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;
- 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
-{
- return m_orientation;
-}
-
-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);
- m_orientation = orientation;
-}
-
-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);
- }
-}
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
deleted file mode 100644
index 6d4939bf96c..00000000000
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ /dev/null
@@ -1,2922 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/Python/AUD_PyAPI.cpp
- * \ingroup audpython
- */
-
-
-#include "AUD_PyAPI.h"
-#include <structmember.h>
-
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.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 reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 boost::shared_ptr<AUD_IFactory>(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=48000)\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;
- double rate = 48000;
-
- if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate))
- return NULL;
-
- Factory *self;
-
- self = (Factory*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- try
- {
- self->factory = new boost::shared_ptr<AUD_IFactory>(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 boost::shared_ptr<AUD_IFactory>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
-
- 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 boost::shared_ptr<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
-
- 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 boost::shared_ptr<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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 = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(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.");
-
-static PyObject *
-Factory_reverse(Factory* self)
-{
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_buffer_doc,
- "buffer()\n\n"
- "Buffers a factory into RAM.\n"
- "This saves CPU usage needed for decoding and file access if the "
- "underlying factory reads from a file on the harddisk, but it "
- "consumes a lot of memory.\n\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: Only known-length factories can be buffered.\n\n"
- ".. warning:: Raw PCM data needs a lot of space, only buffer "
- "short factories.");
-
-static PyObject *
-Factory_buffer(Factory* self)
-{
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_square_doc,
- "square(threshold = 0)\n\n"
- "Makes a square wave out of an audio wave by setting all samples "
- "with a amplitude >= threshold to 1, all <= -threshold to -1 and "
- "all between to 0.\n\n"
- ":arg threshold: Threshold value over which an amplitude counts "
- "non-zero.\n"
- ":type threshold: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_square(Factory* self, PyObject *args)
-{
- float threshold = 0;
-
- if(!PyArg_ParseTuple(args, "|f:square", &threshold))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), threshold));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_filter_doc,
- "filter(b, a = (1))\n\n"
- "Filters a factory with the supplied IIR filter coefficients.\n"
- "Without the second parameter you'll get a FIR filter.\n"
- "If the first value of the a sequence is 0 it will be set to 1 "
- "automatically.\n"
- "If the first value of the a sequence is neither 0 nor 1, all "
- "filter coefficients will be scaled by this value so that it is 1 "
- "in the end, you don't have to scale yourself.\n\n"
- ":arg b: The nominator filter coefficients.\n"
- ":type b: sequence of float\n"
- ":arg a: The denominator filter coefficients.\n"
- ":type a: sequence of float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_filter(Factory* self, PyObject *args)
-{
- PyObject *py_b;
- PyObject *py_a = NULL;
- Py_ssize_t py_a_len;
- Py_ssize_t py_b_len;
-
- if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
- return NULL;
-
- if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a)))
- {
- PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
- return NULL;
- }
-
- py_a_len= py_a ? PySequence_Size(py_a) : 0;
- py_b_len= PySequence_Size(py_b);
-
- if(!py_b_len || ((py_a != NULL) && !py_a_len))
- {
- PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
- return NULL;
- }
-
- std::vector<float> a, b;
- PyObject *py_value;
- float value;
-
- for(Py_ssize_t i = 0; i < py_b_len; i++)
- {
- py_value = PySequence_GetItem(py_b, i);
- value= (float)PyFloat_AsDouble(py_value);
- Py_DECREF(py_value);
-
- if (value==-1.0f && PyErr_Occurred()) {
- return NULL;
- }
-
- b.push_back(value);
- }
-
- if(py_a)
- {
- for(Py_ssize_t i = 0; i < py_a_len; i++)
- {
- py_value = PySequence_GetItem(py_a, i);
- value= (float)PyFloat_AsDouble(py_value);
- Py_DECREF(py_value);
-
- if (value==-1.0f && PyErr_Occurred()) {
- return NULL;
- }
-
- a.push_back(value);
- }
-
- if(a[0] == 0)
- a[0] = 1;
- }
- else
- a.push_back(1);
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), b, a));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-static PyMethodDef Factory_methods[] = {
- {"sine", (PyCFunction)Factory_sine, METH_VARARGS | METH_CLASS,
- M_aud_Factory_sine_doc
- },
- {"file", (PyCFunction)Factory_file, METH_VARARGS | METH_CLASS,
- M_aud_Factory_file_doc
- },
- {"lowpass", (PyCFunction)Factory_lowpass, METH_VARARGS,
- M_aud_Factory_lowpass_doc
- },
- {"delay", (PyCFunction)Factory_delay, METH_VARARGS,
- M_aud_Factory_delay_doc
- },
- {"join", (PyCFunction)Factory_join, METH_O,
- M_aud_Factory_join_doc
- },
- {"highpass", (PyCFunction)Factory_highpass, METH_VARARGS,
- M_aud_Factory_highpass_doc
- },
- {"limit", (PyCFunction)Factory_limit, METH_VARARGS,
- M_aud_Factory_limit_doc
- },
- {"pitch", (PyCFunction)Factory_pitch, METH_VARARGS,
- M_aud_Factory_pitch_doc
- },
- {"volume", (PyCFunction)Factory_volume, METH_VARARGS,
- M_aud_Factory_volume_doc
- },
- {"fadein", (PyCFunction)Factory_fadein, METH_VARARGS,
- M_aud_Factory_fadein_doc
- },
- {"fadeout", (PyCFunction)Factory_fadeout, METH_VARARGS,
- M_aud_Factory_fadeout_doc
- },
- {"loop", (PyCFunction)Factory_loop, METH_VARARGS,
- M_aud_Factory_loop_doc
- },
- {"mix", (PyCFunction)Factory_mix, METH_O,
- M_aud_Factory_mix_doc
- },
- {"pingpong", (PyCFunction)Factory_pingpong, METH_NOARGS,
- M_aud_Factory_pingpong_doc
- },
- {"reverse", (PyCFunction)Factory_reverse, METH_NOARGS,
- M_aud_Factory_reverse_doc
- },
- {"buffer", (PyCFunction)Factory_buffer, METH_NOARGS,
- M_aud_Factory_buffer_doc
- },
- {"square", (PyCFunction)Factory_square, METH_VARARGS,
- M_aud_Factory_square_doc
- },
- {"filter", (PyCFunction)Factory_filter, METH_VARARGS,
- M_aud_Factory_filter_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Factory_doc,
- "Factory objects are immutable and represent a sound that can be "
- "played simultaneously multiple times. They are called factories "
- "because they create reader objects internally that are used for "
- "playback.");
-
-static PyTypeObject FactoryType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Factory", /* tp_name */
- sizeof(Factory), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Factory_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Factory_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Factory_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- Factory_new, /* tp_new */
-};
-
-// ========== Handle ==================================================
-
-static void
-Handle_dealloc(Handle* self)
-{
- if(self->handle)
- delete reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-PyDoc_STRVAR(M_aud_Handle_pause_doc,
- "pause()\n\n"
- "Pauses playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool");
-
-static PyObject *
-Handle_pause(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->pause());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_resume_doc,
- "resume()\n\n"
- "Resumes playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool");
-
-static PyObject *
-Handle_resume(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->resume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_stop_doc,
- "stop()\n\n"
- "Stops playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool\n\n"
- ".. note:: This makes the handle invalid.");
-
-static PyObject *
-Handle_stop(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->stop());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static PyMethodDef Handle_methods[] = {
- {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
- M_aud_Handle_pause_doc
- },
- {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
- M_aud_Handle_resume_doc
- },
- {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
- M_aud_Handle_stop_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Handle_position_doc,
- "The playback position of the sound in seconds.");
-
-static PyObject *
-Handle_get_position(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPosition());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_position(Handle *self, PyObject *args, void* nothing)
-{
- float position;
-
- if(!PyArg_Parse(args, "f:position", &position))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->seek(position))
- return 0;
- PyErr_SetString(AUDError, "Couldn't seek the sound!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_keep_doc,
- "Whether the sound should be kept paused in the device when its "
- "end is reached.\n"
- "This can be used to seek the sound to some position and start "
- "playback again.\n\n"
- ".. warning:: If this is set to true and you forget stopping this "
- "equals a memory leak as the handle exists until the device is "
- "destroyed.");
-
-static PyObject *
-Handle_get_keep(Handle *self, void* nothing)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getKeep());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_keep(Handle *self, PyObject *args, void* nothing)
-{
- if(!PyBool_Check(args))
- {
- PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
- return -1;
- }
-
- bool keep = args == Py_True;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setKeep(keep))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_status_doc,
- "Whether the sound is playing, paused or stopped (=invalid).");
-
-static PyObject *
-Handle_get_status(Handle *self, void* nothing)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getStatus());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_doc,
- "The volume of the sound.");
-
-static PyObject *
-Handle_get_volume(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getVolume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume", &volume))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setVolume(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the sound volume!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_pitch_doc,
- "The pitch of the sound.");
-
-static PyObject *
-Handle_get_pitch(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPitch());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_pitch(Handle *self, PyObject *args, void* nothing)
-{
- float pitch;
-
- if(!PyArg_Parse(args, "f:pitch", &pitch))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setPitch(pitch))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
- "The (remaining) loop count of the sound. A negative value indicates infinity.");
-
-static PyObject *
-Handle_get_loop_count(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("i", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getLoopCount());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_loop_count(Handle *self, PyObject *args, void* nothing)
-{
- int loops;
-
- if(!PyArg_Parse(args, "i:loop_count", &loops))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the loop count!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_location_doc,
- "The source's location in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Handle_get_location(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 v = handle->getSourceLocation();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_location(Handle *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 location(x, y, z);
- if(handle->setSourceLocation(location))
- return 0;
- PyErr_SetString(AUDError, "Location couldn't be set!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_velocity_doc,
- "The source's velocity in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Handle_get_velocity(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 v = handle->getSourceVelocity();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_velocity(Handle *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 velocity(x, y, z);
- if(handle->setSourceVelocity(velocity))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the velocity!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_orientation_doc,
- "The source's orientation in 3D space as quaternion, a 4 float tuple.");
-
-static PyObject *
-Handle_get_orientation(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Quaternion o = handle->getSourceOrientation();
- return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_orientation(Handle *self, PyObject *args, void* nothing)
-{
- float w, x, y, z;
-
- if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Quaternion orientation(w, x, y, z);
- if(handle->setSourceOrientation(orientation))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the orientation!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_relative_doc,
- "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
-
-static PyObject *
-Handle_get_relative(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return PyBool_FromLong((long)handle->isRelative());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_relative(Handle *self, PyObject *args, void* nothing)
-{
- if(!PyBool_Check(args))
- {
- PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
- return -1;
- }
-
- bool relative = (args == Py_True);
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setRelative(relative))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the relativeness!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
- "The minimum volume of the source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_volume_minimum(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getVolumeMinimum());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume_minimum(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume_minimum", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setVolumeMinimum(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
- "The maximum volume of the source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_volume_maximum(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getVolumeMaximum());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume_maximum(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume_maximum", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setVolumeMaximum(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
- "The reference distance of the source.\n"
- "At this distance the volume will be exactly :attr:`volume`.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_distance_reference(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getDistanceReference());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_distance_reference(Handle *self, PyObject *args, void* nothing)
-{
- float distance;
-
- if(!PyArg_Parse(args, "f:distance_reference", &distance))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setDistanceReference(distance))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the reference distance!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
- "The maximum distance of the source.\n"
- "If the listener is further away the source volume will be 0.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_distance_maximum(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getDistanceMaximum());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_distance_maximum(Handle *self, PyObject *args, void* nothing)
-{
- float distance;
-
- if(!PyArg_Parse(args, "f:distance_maximum", &distance))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setDistanceMaximum(distance))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
- "This factor is used for distance based attenuation of the "
- "source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_attenuation(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getAttenuation());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_attenuation(Handle *self, PyObject *args, void* nothing)
-{
- float factor;
-
- if(!PyArg_Parse(args, "f:attenuation", &factor))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setAttenuation(factor))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the attenuation!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
- "The opening angle of the inner cone of the source. If the cone "
- "values of a source are set there are two (audible) cones with "
- "the apex at the :attr:`location` of the source and with infinite "
- "height, heading in the direction of the source's "
- ":attr:`orientation`.\n"
- "In the inner cone the volume is normal. Outside the outer cone "
- "the volume will be :attr:`cone_volume_outer` and in the area "
- "between the volume will be interpolated linearly.");
-
-static PyObject *
-Handle_get_cone_angle_inner(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getConeAngleInner());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_angle_inner(Handle *self, PyObject *args, void* nothing)
-{
- float angle;
-
- if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeAngleInner(angle))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
- "The opening angle of the outer cone of the source.\n\n"
- ".. seealso:: :attr:`cone_angle_inner`");
-
-static PyObject *
-Handle_get_cone_angle_outer(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getConeAngleOuter());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_angle_outer(Handle *self, PyObject *args, void* nothing)
-{
- float angle;
-
- if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeAngleOuter(angle))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
- "The volume outside the outer cone of the source.\n\n"
- ".. seealso:: :attr:`cone_angle_inner`");
-
-static PyObject *
-Handle_get_cone_volume_outer(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- return Py_BuildValue("f", handle->getConeVolumeOuter());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_volume_outer(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeVolumeOuter(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-static PyGetSetDef Handle_properties[] = {
- {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
- M_aud_Handle_position_doc, NULL },
- {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
- M_aud_Handle_keep_doc, NULL },
- {(char*)"status", (getter)Handle_get_status, NULL,
- M_aud_Handle_status_doc, NULL },
- {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
- M_aud_Handle_volume_doc, NULL },
- {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
- M_aud_Handle_pitch_doc, NULL },
- {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
- M_aud_Handle_loop_count_doc, NULL },
- {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
- M_aud_Handle_location_doc, NULL },
- {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
- M_aud_Handle_velocity_doc, NULL },
- {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
- M_aud_Handle_orientation_doc, NULL },
- {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
- M_aud_Handle_relative_doc, NULL },
- {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
- M_aud_Handle_volume_minimum_doc, NULL },
- {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
- M_aud_Handle_volume_maximum_doc, NULL },
- {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
- M_aud_Handle_distance_reference_doc, NULL },
- {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
- M_aud_Handle_distance_maximum_doc, NULL },
- {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
- M_aud_Handle_attenuation_doc, NULL },
- {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
- M_aud_Handle_cone_angle_inner_doc, NULL },
- {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
- M_aud_Handle_cone_angle_outer_doc, NULL },
- {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
- M_aud_Handle_cone_volume_outer_doc, NULL },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Handle_doc,
- "Handle objects are playback handles that can be used to control "
- "playback of a sound. If a sound is played back multiple times "
- "then there are as many handles.");
-
-static PyTypeObject HandleType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Handle", /* tp_name */
- sizeof(Handle), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Handle_dealloc,/* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Handle_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Handle_methods, /* tp_methods */
- 0, /* tp_members */
- Handle_properties, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-// ========== Device ==================================================
-
-static void
-Device_dealloc(Device* self)
-{
- if(self->device)
- delete reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *
-Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Device *self;
-
- static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
- int device;
- double rate = AUD_RATE_48000;
- int channels = AUD_CHANNELS_STEREO;
- int format = AUD_FORMAT_FLOAT32;
- int buffersize = AUD_DEFAULT_BUFFER_SIZE;
- const char* name = "Audaspace";
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|diiis:Device", const_cast<char**>(kwlist),
- &device, &rate, &channels, &format, &buffersize, &name))
- return NULL;
-
- if(buffersize < 128)
- {
- PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
- return NULL;
- }
-
- self = (Device*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- AUD_DeviceSpecs specs;
- specs.channels = (AUD_Channels)channels;
- specs.format = (AUD_SampleFormat)format;
- specs.rate = (AUD_SampleRate)rate;
-
- self->device = NULL;
-
- try
- {
- switch(device)
- {
- case AUD_DEVICE_NULL:
- (void)specs; /* quiet warning when others disabled */
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
- break;
- case AUD_DEVICE_OPENAL:
-#ifdef WITH_OPENAL
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
-#endif
- break;
- case AUD_DEVICE_SDL:
-#ifdef WITH_SDL
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
-#endif
- break;
- case AUD_DEVICE_JACK:
-#ifdef WITH_JACK
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
-#endif
- break;
- case AUD_DEVICE_READ:
- break;
- }
-
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-
- if(!self->device)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, "Unsupported device type!");
- return NULL;
- }
- }
-
- return (PyObject *)self;
-}
-
-PyDoc_STRVAR(M_aud_Device_play_doc,
- "play(factory, keep=False)\n\n"
- "Plays a factory.\n\n"
- ":arg factory: The factory to play.\n"
- ":type factory: :class:`Factory`\n"
- ":arg keep: See :attr:`Handle.keep`.\n"
- ":type keep: bool\n"
- ":return: The playback handle with which playback can be "
- "controlled with.\n"
- ":rtype: :class:`Handle`");
-
-static PyObject *
-Device_play(Device *self, PyObject *args, PyObject *kwds)
-{
- PyObject *object;
- PyObject *keepo = NULL;
-
- bool keep = false;
-
- static const char *kwlist[] = {"factory", "keep", NULL};
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo))
- return NULL;
-
- if(!PyObject_TypeCheck(object, &FactoryType))
- {
- PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
- return NULL;
- }
-
- if(keepo != NULL)
- {
- if(!PyBool_Check(keepo))
- {
- PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
- return NULL;
- }
-
- keep = keepo == Py_True;
- }
-
- Factory* sound = (Factory*)object;
- Handle *handle;
-
- handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
- if(handle != NULL)
- {
- try
- {
- handle->handle = new boost::shared_ptr<AUD_IHandle>((*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(sound->factory), keep));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(handle);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)handle;
-}
-
-PyDoc_STRVAR(M_aud_Device_stopAll_doc,
- "stopAll()\n\n"
- "Stops all playing and paused sounds.");
-
-static PyObject *
-Device_stopAll(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->stopAll();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_lock_doc,
- "lock()\n\n"
- "Locks the device so that it's guaranteed, that no samples are "
- "read from the streams until :meth:`unlock` is called.\n"
- "This is useful if you want to do start/stop/pause/resume some "
- "sounds at the same time.\n\n"
- ".. note:: The device has to be unlocked as often as locked to be "
- "able to continue playback.\n\n"
- ".. warning:: Make sure the time between locking and unlocking is "
- "as short as possible to avoid clicks.");
-
-static PyObject *
-Device_lock(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->lock();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_unlock_doc,
- "unlock()\n\n"
- "Unlocks the device after a lock call, see :meth:`lock` for "
- "details.");
-
-static PyObject *
-Device_unlock(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->unlock();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static PyMethodDef Device_methods[] = {
- {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
- M_aud_Device_play_doc
- },
- {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS,
- M_aud_Device_stopAll_doc
- },
- {"lock", (PyCFunction)Device_lock, METH_NOARGS,
- M_aud_Device_lock_doc
- },
- {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
- M_aud_Device_unlock_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Device_rate_doc,
- "The sampling rate of the device in Hz.");
-
-static PyObject *
-Device_get_rate(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("d", specs.rate);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_format_doc,
- "The native sample format of the device.");
-
-static PyObject *
-Device_get_format(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("i", specs.format);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_channels_doc,
- "The channel count of the device.");
-
-static PyObject *
-Device_get_channels(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("i", specs.channels);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_volume_doc,
- "The overall volume of the device.");
-
-static PyObject *
-Device_get_volume(Device *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getVolume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_volume(Device *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume", &volume))
- return -1;
-
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->setVolume(volume);
- return 0;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return -1;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_location_doc,
- "The listeners's location in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Device_get_listener_location(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 v = device->getListenerLocation();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_location(Device *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 location(x, y, z);
- device->setListenerLocation(location);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
- "The listener's velocity in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Device_get_listener_velocity(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 v = device->getListenerVelocity();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_velocity(Device *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 velocity(x, y, z);
- device->setListenerVelocity(velocity);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
- "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
-
-static PyObject *
-Device_get_listener_orientation(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Quaternion o = device->getListenerOrientation();
- return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_orientation(Device *self, PyObject *args, void* nothing)
-{
- float w, x, y, z;
-
- if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Quaternion orientation(w, x, y, z);
- device->setListenerOrientation(orientation);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
- "The speed of sound of the device.\n"
- "The speed of sound in air is typically 343.3 m/s.");
-
-static PyObject *
-Device_get_speed_of_sound(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- return Py_BuildValue("f", device->getSpeedOfSound());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_speed_of_sound(Device *self, PyObject *args, void* nothing)
-{
- float speed;
-
- if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setSpeedOfSound(speed);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
- "The doppler factor of the device.\n"
- "This factor is a scaling factor for the velocity vectors in "
- "doppler calculation. So a value bigger than 1 will exaggerate "
- "the effect as it raises the velocity.");
-
-static PyObject *
-Device_get_doppler_factor(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- return Py_BuildValue("f", device->getDopplerFactor());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_doppler_factor(Device *self, PyObject *args, void* nothing)
-{
- float factor;
-
- if(!PyArg_Parse(args, "f:doppler_factor", &factor))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setDopplerFactor(factor);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_distance_model_doc,
- "The distance model of the device.\n\n"
- ".. seealso:: `OpenAL documentation <https://www.openal.org/documentation>`");
-
-static PyObject *
-Device_get_distance_model(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- return Py_BuildValue("i", int(device->getDistanceModel()));
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_distance_model(Device *self, PyObject *args, void* nothing)
-{
- int model;
-
- if(!PyArg_Parse(args, "i:distance_model", &model))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setDistanceModel(AUD_DistanceModel(model));
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-static PyGetSetDef Device_properties[] = {
- {(char*)"rate", (getter)Device_get_rate, NULL,
- M_aud_Device_rate_doc, NULL },
- {(char*)"format", (getter)Device_get_format, NULL,
- M_aud_Device_format_doc, NULL },
- {(char*)"channels", (getter)Device_get_channels, NULL,
- M_aud_Device_channels_doc, NULL },
- {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
- M_aud_Device_volume_doc, NULL },
- {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
- M_aud_Device_listener_location_doc, NULL },
- {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
- M_aud_Device_listener_velocity_doc, NULL },
- {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
- M_aud_Device_listener_orientation_doc, NULL },
- {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
- M_aud_Device_speed_of_sound_doc, NULL },
- {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
- M_aud_Device_doppler_factor_doc, NULL },
- {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
- M_aud_Device_distance_model_doc, NULL },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Device_doc,
- "Device objects represent an audio output backend like OpenAL or "
- "SDL, but might also represent a file output or RAM buffer "
- "output.");
-
-static PyTypeObject DeviceType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Device", /* tp_name */
- sizeof(Device), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Device_dealloc,/* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Device_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Device_methods, /* tp_methods */
- 0, /* tp_members */
- Device_properties, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- Device_new, /* tp_new */
-};
-
-PyObject *
-Device_empty()
-{
- return DeviceType.tp_alloc(&DeviceType, 0);
-}
-
-PyObject *
-Factory_empty()
-{
- return FactoryType.tp_alloc(&FactoryType, 0);
-}
-
-Factory*
-checkFactory(PyObject *factory)
-{
- if(!PyObject_TypeCheck(factory, &FactoryType))
- {
- PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
- return NULL;
- }
-
- return (Factory*)factory;
-}
-
-
-// ====================================================================
-
-PyDoc_STRVAR(M_aud_doc,
- "This module provides access to the audaspace audio library.");
-
-static struct PyModuleDef audmodule = {
- PyModuleDef_HEAD_INIT,
- "aud", /* name of module */
- M_aud_doc, /* module documentation */
- -1, /* size of per-interpreter state of the module,
- or -1 if the module keeps state in global variables. */
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_aud(void)
-{
- PyObject *m;
-
- if(PyType_Ready(&FactoryType) < 0)
- return NULL;
-
- if(PyType_Ready(&DeviceType) < 0)
- return NULL;
-
- if(PyType_Ready(&HandleType) < 0)
- return NULL;
-
- m = PyModule_Create(&audmodule);
- if(m == NULL)
- return NULL;
-
- Py_INCREF(&FactoryType);
- PyModule_AddObject(m, "Factory", (PyObject *)&FactoryType);
-
- Py_INCREF(&DeviceType);
- PyModule_AddObject(m, "Device", (PyObject *)&DeviceType);
-
- Py_INCREF(&HandleType);
- PyModule_AddObject(m, "Handle", (PyObject *)&HandleType);
-
- AUDError = PyErr_NewException("aud.error", NULL, NULL);
- Py_INCREF(AUDError);
- PyModule_AddObject(m, "error", AUDError);
-
- // device constants
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_NULL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_OPENAL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_SDL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_JACK);
- //PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_READ);
- // format constants
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT32);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT64);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_INVALID);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S16);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S24);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S32);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_U8);
- // status constants
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_STOPPED);
- // distance model constants
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVALID);
-
- return m;
-}
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
deleted file mode 100644
index 0183a2df6b2..00000000000
--- a/intern/audaspace/Python/AUD_PyAPI.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/Python/AUD_PyAPI.h
- * \ingroup audpython
- */
-
-
-#ifndef __AUD_PYAPI_H__
-#define __AUD_PYAPI_H__
-
-#include "Python.h"
-
-#ifdef __cplusplus
-extern "C" {
-#else
-typedef void AUD_IFactory;
-typedef void AUD_IDevice;
-typedef void AUD_IHandle;
-#endif
-
-typedef void AUD_Reference_AUD_IFactory;
-typedef void AUD_Reference_AUD_IDevice;
-typedef void AUD_Reference_AUD_IHandle;
-
-typedef struct {
- PyObject_HEAD
- PyObject *child_list;
- AUD_Reference_AUD_IFactory* factory;
-} Factory;
-
-typedef struct {
- PyObject_HEAD
- AUD_Reference_AUD_IHandle* handle;
-} Handle;
-
-typedef struct {
- PyObject_HEAD
- AUD_Reference_AUD_IDevice* device;
-} Device;
-
-PyMODINIT_FUNC
-PyInit_aud(void);
-
-extern PyObject *Device_empty();
-extern PyObject *Factory_empty();
-extern Factory *checkFactory(PyObject *factory);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__AUD_PYAPI_H__
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp
deleted file mode 100644
index 23729a7a171..00000000000
--- a/intern/audaspace/SDL/AUD_SDLDevice.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SDL/AUD_SDLDevice.cpp
- * \ingroup audsdl
- */
-
-
-#include "AUD_SDLDevice.h"
-#include "AUD_IReader.h"
-
-void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
-{
- AUD_SDLDevice* device = (AUD_SDLDevice*)data;
-
- device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
-}
-
-static const char* open_error = "AUD_SDLDevice: Device couldn't be opened.";
-static const char* format_error = "AUD_SDLDevice: Obtained unsupported sample "
- "format.";
-
-AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
-{
- if(specs.channels == AUD_CHANNELS_INVALID)
- specs.channels = AUD_CHANNELS_STEREO;
- if(specs.format == AUD_FORMAT_INVALID)
- specs.format = AUD_FORMAT_S16;
- if(specs.rate == AUD_RATE_INVALID)
- specs.rate = AUD_RATE_48000;
-
- m_specs = specs;
-
- SDL_AudioSpec format, obtained;
-
- format.freq = m_specs.rate;
- if(m_specs.format == AUD_FORMAT_U8)
- format.format = AUDIO_U8;
- else
- format.format = AUDIO_S16SYS;
- format.channels = m_specs.channels;
- format.samples = buffersize;
- format.callback = AUD_SDLDevice::SDL_mix;
- format.userdata = this;
-
- if(SDL_OpenAudio(&format, &obtained) != 0)
- AUD_THROW(AUD_ERROR_SDL, open_error);
-
- m_specs.rate = (AUD_SampleRate)obtained.freq;
- m_specs.channels = (AUD_Channels)obtained.channels;
- if(obtained.format == AUDIO_U8)
- m_specs.format = AUD_FORMAT_U8;
- else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
- m_specs.format = AUD_FORMAT_S16;
- else
- {
- SDL_CloseAudio();
- AUD_THROW(AUD_ERROR_SDL, format_error);
- }
-
- create();
-}
-
-AUD_SDLDevice::~AUD_SDLDevice()
-{
- lock();
- SDL_CloseAudio();
- unlock();
-
- destroy();
-}
-
-void AUD_SDLDevice::playing(bool playing)
-{
- SDL_PauseAudio(playing ? 0 : 1);
-}
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.h b/intern/audaspace/SDL/AUD_SDLDevice.h
deleted file mode 100644
index c4ff9e80aa9..00000000000
--- a/intern/audaspace/SDL/AUD_SDLDevice.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SDL/AUD_SDLDevice.h
- * \ingroup audsdl
- */
-
-
-#ifndef __AUD_SDLDEVICE_H__
-#define __AUD_SDLDEVICE_H__
-
-#include "AUD_SoftwareDevice.h"
-
-/* SDL force defines __SSE__ and __SSE2__ flags, which generates warnings
- * because we pass those defines via command line as well. For until there's
- * proper ifndef added to SDL headers we ignore the redefinition warning.
- */
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable : 4005)
-#endif
-#include <SDL.h>
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-/**
- * This device plays back through SDL, the simple direct media layer.
- */
-class AUD_SDLDevice : public AUD_SoftwareDevice
-{
-private:
- /**
- * Mixes the next bytes into the buffer.
- * \param data The SDL device.
- * \param buffer The target buffer.
- * \param length The length in bytes to be filled.
- */
- static void SDL_mix(void *data, Uint8* buffer, int length);
-
- // hide copy constructor and operator=
- AUD_SDLDevice(const AUD_SDLDevice&);
- AUD_SDLDevice& operator=(const AUD_SDLDevice&);
-
-protected:
- virtual void playing(bool playing);
-
-public:
- /**
- * Opens the SDL 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.
- * \exception AUD_Exception Thrown if the audio device cannot be opened.
- */
- AUD_SDLDevice(AUD_DeviceSpecs specs,
- int buffersize = AUD_DEFAULT_BUFFER_SIZE);
-
- /**
- * Closes the SDL audio device.
- */
- virtual ~AUD_SDLDevice();
-};
-
-#endif //__AUD_SDLDEVICE_H__
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
deleted file mode 100644
index 6861e878abc..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SRC/AUD_SRCResampleFactory.cpp
- * \ingroup audsrc
- */
-
-
-#include "AUD_SRCResampleFactory.h"
-#include "AUD_SRCResampleReader.h"
-
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-AUD_Reference<AUD_IReader> AUD_SRCResampleFactory::createReader()
-{
- return new AUD_SRCResampleReader(getReader(), m_specs.specs);
-}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
deleted file mode 100644
index 858bb0c130a..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SRC/AUD_SRCResampleFactory.h
- * \ingroup audsrc
- */
-
-
-#ifndef __AUD_SRCRESAMPLEFACTORY_H__
-#define __AUD_SRCRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that uses libsamplerate for
- * resampling.
- */
-class AUD_SRCResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_SRCResampleFactory(const AUD_SRCResampleFactory&);
- AUD_SRCResampleFactory& operator=(const AUD_SRCResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual AUD_Reference<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SRCRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
deleted file mode 100644
index 242a7135aff..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SRC/AUD_SRCResampleReader.cpp
- * \ingroup audsrc
- */
-
-
-#include "AUD_SRCResampleReader.h"
-
-#include <cmath>
-#include <cstring>
-#include <cstdio>
-
-static long src_callback(void *cb_data, float **data)
-{
- return ((AUD_SRCResampleReader*)cb_data)->doCallback(data);
-}
-
-static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
- "created.";
-
-AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
- AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(reader->getSpecs().channels),
- m_position(0)
-{
- int error;
- m_src = src_callback_new(src_callback,
- SRC_SINC_MEDIUM_QUALITY,
- m_channels,
- &error,
- this);
-
- if(!m_src)
- {
- // XXX printf("%s\n", src_strerror(error));
- AUD_THROW(AUD_ERROR_SRC, state_error);
- }
-}
-
-AUD_SRCResampleReader::~AUD_SRCResampleReader()
-{
- src_delete(m_src);
-}
-
-long AUD_SRCResampleReader::doCallback(float** data)
-{
- AUD_Specs specs;
- specs.channels = m_channels;
- specs.rate = m_rate;
-
- int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(specs);
-
- *data = m_buffer.getBuffer();
- m_reader->read(length, m_eos, *data);
-
- return length;
-}
-
-void AUD_SRCResampleReader::seek(int position)
-{
- AUD_Specs specs = m_reader->getSpecs();
- double factor = double(m_rate) / double(specs.rate);
- m_reader->seek(position / factor);
- src_reset(m_src);
- m_position = position;
-}
-
-int AUD_SRCResampleReader::getLength() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- double factor = double(m_rate) / double(specs.rate);
- return m_reader->getLength() * factor;
-}
-
-int AUD_SRCResampleReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SRCResampleReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.rate = m_rate;
- return specs;
-}
-
-void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
-
- double factor = double(m_rate) / double(specs.rate);
-
- specs.rate = m_rate;
-
- int size = length;
-
- m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs));
-
- if(specs.channels != m_channels)
- {
- src_delete(m_src);
-
- m_channels = specs.channels;
-
- int error;
- m_src = src_callback_new(src_callback,
- SRC_SINC_MEDIUM_QUALITY,
- m_channels,
- &error,
- this);
-
- if(!m_src)
- {
- // XXX printf("%s\n", src_strerror(error));
- AUD_THROW(AUD_ERROR_SRC, state_error);
- }
- }
-
- m_eos = false;
-
- length = src_callback_read(m_src, factor, length, buffer);
-
- m_position += length;
-
- eos = m_eos && (length < size);
-}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
deleted file mode 100644
index 891b28b0993..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/SRC/AUD_SRCResampleReader.h
- * \ingroup audsrc
- */
-
-
-#ifndef __AUD_SRCRESAMPLEREADER_H__
-#define __AUD_SRCRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-#include <samplerate.h>
-
-/**
- * This resampling reader uses libsamplerate for resampling.
- */
-class AUD_SRCResampleReader : public AUD_ResampleReader
-{
-private:
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The src state structure.
- */
- SRC_STATE* m_src;
-
- /**
- * The current playback position;
- */
- int m_position;
-
- /**
- * Whether reader reached end of stream.
- */
- bool m_eos;
-
- // hide copy constructor and operator=
- AUD_SRCResampleReader(const AUD_SRCResampleReader&);
- AUD_SRCResampleReader& operator=(const AUD_SRCResampleReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- * \exception AUD_Exception Thrown if the source specification cannot be
- * resampled to the target specification.
- */
- AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
-
- /**
- * Destroys the reader.
- */
- ~AUD_SRCResampleReader();
-
- /**
- * The callback function for SRC.
- * \warning Do not call!
- * \param data The pointer to the float data.
- * \return The count of samples in the float data.
- */
- long doCallback(float** data);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SRCRESAMPLEREADER_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
deleted file mode 100644
index 403c367fccc..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGFactory.h"
-#include "AUD_FFMPEGReader.h"
-
-AUD_FFMPEGFactory::AUD_FFMPEGFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_FFMPEGFactory::AUD_FFMPEGFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_FFMPEGFactory::createReader()
-{
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_filename));
-}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
deleted file mode 100644
index 23d0f07ed0b..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGFactory.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGFACTORY_H__
-#define __AUD_FFMPEGFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory reads a sound file via ffmpeg.
- * \warning Notice that the needed formats and codecs have to be registered
- * for ffmpeg before this class can be used.
- */
-class AUD_FFMPEGFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- const std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_FFMPEGFactory(const AUD_FFMPEGFactory&);
- AUD_FFMPEGFactory& operator=(const AUD_FFMPEGFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_FFMPEGFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_FFMPEGFactory(const data_t* buffer, int size);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_FFMPEGFACTORY_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
deleted file mode 100644
index e9eea195208..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGReader.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGReader.h"
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libavformat/avio.h>
-#include "ffmpeg_compat.h"
-}
-
-int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer)
-{
-#ifdef FFMPEG_HAVE_DECODE_AUDIO4
- AVFrame* frame = NULL;
- int got_frame;
- int read_length;
- uint8_t* orig_data = packet.data;
- int orig_size = packet.size;
-
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
- while(packet.size > 0)
- {
- got_frame = 0;
-
- if(!frame)
- frame = av_frame_alloc();
- else
- av_frame_unref(frame);
-
- read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
- if(read_length < 0)
- break;
-
- if(got_frame)
- {
- int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
-
- if(buf_size - buf_pos < data_size)
- {
- buffer.resize(buf_size + data_size, true);
- buf_size += data_size;
- }
-
- if(m_tointerleave)
- {
- int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
- for(int channel = 0; channel < m_codecCtx->channels; channel++)
- {
- for(int i = 0; i < frame->nb_samples; i++)
- {
- memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- frame->data[channel] + i * single_size, single_size);
- }
- }
- }
- else
- memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
-
- buf_pos += data_size;
- }
- packet.size -= read_length;
- packet.data += read_length;
- }
-
- packet.data = orig_data;
- packet.size = orig_size;
- av_free(frame);
-
- return buf_pos;
-#else
- // save packet parameters
- uint8_t *audio_pkg_data = packet.data;
- int audio_pkg_size = packet.size;
-
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
- int read_length, data_size;
-
- AVPacket tmp_pkt;
-
- av_init_packet(&tmp_pkt);
-
- // as long as there is still data in the package
- while(audio_pkg_size > 0)
- {
- // resize buffer if needed
- if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
- {
- buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
- buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
- }
-
- // read samples from the packet
- data_size = buf_size - buf_pos;
-
- tmp_pkt.data = audio_pkg_data;
- tmp_pkt.size = audio_pkg_size;
-
- read_length = avcodec_decode_audio3(
- m_codecCtx,
- (int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
- &data_size, &tmp_pkt);
-
- // read error, next packet!
- if(read_length < 0)
- break;
-
- buf_pos += data_size;
-
- // move packet parameters
- audio_pkg_data += read_length;
- audio_pkg_size -= read_length;
- }
-
- return buf_pos;
-#endif
-}
-
-static const char* streaminfo_error = "AUD_FFMPEGReader: Stream info couldn't "
- "be found.";
-static const char* noaudio_error = "AUD_FFMPEGReader: File doesn't include an "
- "audio stream.";
-static const char* nodecoder_error = "AUD_FFMPEGReader: No decoder found for "
- "the audio stream.";
-static const char* codecopen_error = "AUD_FFMPEGReader: Codec couldn't be "
- "opened.";
-static const char* format_error = "AUD_FFMPEGReader: Unsupported sample "
- "format.";
-
-void AUD_FFMPEGReader::init()
-{
- m_position = 0;
- m_pkgbuf_left = 0;
-
- if(avformat_find_stream_info(m_formatCtx, NULL) < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
-
- // find audio stream and codec
- m_stream = -1;
-
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- {
- if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- }
-
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG, noaudio_error);
-
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
-
- if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
-
- // XXX this prints file information to stdout:
- //dump_format(m_formatCtx, 0, NULL, 0);
-
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
-
- switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
- {
- case AV_SAMPLE_FMT_U8:
- m_convert = AUD_convert_u8_float;
- m_specs.format = AUD_FORMAT_U8;
- break;
- case AV_SAMPLE_FMT_S16:
- m_convert = AUD_convert_s16_float;
- m_specs.format = AUD_FORMAT_S16;
- break;
- case AV_SAMPLE_FMT_S32:
- m_convert = AUD_convert_s32_float;
- m_specs.format = AUD_FORMAT_S32;
- break;
- case AV_SAMPLE_FMT_FLT:
- m_convert = AUD_convert_copy<float>;
- m_specs.format = AUD_FORMAT_FLOAT32;
- break;
- case AV_SAMPLE_FMT_DBL:
- m_convert = AUD_convert_double_float;
- m_specs.format = AUD_FORMAT_FLOAT64;
- break;
- default:
- AUD_THROW(AUD_ERROR_FFMPEG, format_error);
- }
-
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
-}
-
-static const char* fileopen_error = "AUD_FFMPEGReader: File couldn't be "
- "opened.";
-
-AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
- m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_formatCtx(NULL),
- m_aviocontext(NULL),
- m_membuf(NULL)
-{
- // open file
- if(avformat_open_input(&m_formatCtx, filename.c_str(), NULL, NULL)!=0)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- try
- {
- init();
- }
- catch(AUD_Exception&)
- {
- avformat_close_input(&m_formatCtx);
- throw;
- }
-}
-
-static const char* streamopen_error = "AUD_FFMPEGReader: Stream couldn't be "
- "opened.";
-
-AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
- m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_membuffer(buffer),
- m_membufferpos(0)
-{
- m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
-
- m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this,
- read_packet, NULL, seek_packet);
-
- if(!m_aviocontext)
- {
- av_free(m_aviocontext);
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
- }
-
- m_formatCtx = avformat_alloc_context();
- m_formatCtx->pb = m_aviocontext;
- if(avformat_open_input(&m_formatCtx, "", NULL, NULL)!=0)
- {
- av_free(m_aviocontext);
- AUD_THROW(AUD_ERROR_FILE, streamopen_error);
- }
-
- try
- {
- init();
- }
- catch(AUD_Exception&)
- {
- avformat_close_input(&m_formatCtx);
- av_free(m_aviocontext);
- throw;
- }
-}
-
-AUD_FFMPEGReader::~AUD_FFMPEGReader()
-{
- avcodec_close(m_codecCtx);
- avformat_close_input(&m_formatCtx);
-}
-
-int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
-{
- AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
-
- int size = AUD_MIN(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos);
-
- if(size < 0)
- return -1;
-
- memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
- reader->m_membufferpos += size;
-
- return size;
-}
-
-int64_t AUD_FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
-{
- AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
-
- switch(whence)
- {
- case SEEK_SET:
- reader->m_membufferpos = 0;
- break;
- case SEEK_END:
- reader->m_membufferpos = reader->m_membuffer->getSize();
- break;
- case AVSEEK_SIZE:
- return reader->m_membuffer->getSize();
- }
-
- return (reader->m_membufferpos += offset);
-}
-
-bool AUD_FFMPEGReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_FFMPEGReader::seek(int position)
-{
- if(position >= 0)
- {
- uint64_t st_time = m_formatCtx->start_time;
- uint64_t seek_pos = ((uint64_t)position) * ((uint64_t)AV_TIME_BASE) / ((uint64_t)m_specs.rate);
-
- if (st_time != AV_NOPTS_VALUE) {
- seek_pos += st_time;
- }
-
- double pts_time_base =
- av_q2d(m_formatCtx->streams[m_stream]->time_base);
- uint64_t pts_st_time =
- ((st_time != AV_NOPTS_VALUE) ? st_time : 0)
- / pts_time_base / (uint64_t) AV_TIME_BASE;
-
- // a value < 0 tells us that seeking failed
- if(av_seek_frame(m_formatCtx, -1, seek_pos,
- AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
- {
- avcodec_flush_buffers(m_codecCtx);
- m_position = position;
-
- AVPacket packet;
- bool search = true;
-
- while(search && av_read_frame(m_formatCtx, &packet) >= 0)
- {
- // is it a frame from the audio stream?
- if(packet.stream_index == m_stream)
- {
- // decode the package
- m_pkgbuf_left = decode(packet, m_pkgbuf);
- search = false;
-
- // check position
- if(packet.pts != AV_NOPTS_VALUE)
- {
- // calculate real position, and read to frame!
- m_position = (packet.pts -
- pts_st_time) * pts_time_base * m_specs.rate;
-
- if(m_position < position)
- {
- // read until we're at the right position
- int length = AUD_DEFAULT_BUFFER_SIZE;
- AUD_Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs));
- bool eos;
- for(int len = position - m_position; len > 0; len -= AUD_DEFAULT_BUFFER_SIZE)
- {
- if(len < AUD_DEFAULT_BUFFER_SIZE)
- length = len;
- read(length, eos, buffer.getBuffer());
- }
- }
- }
- }
- av_free_packet(&packet);
- }
- }
- else
- {
- fprintf(stderr, "seeking failed!\n");
- // Seeking failed, do nothing.
- }
- }
-}
-
-int AUD_FFMPEGReader::getLength() const
-{
- // return approximated remaning size
- return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
- / AV_TIME_BASE)-m_position;
-}
-
-int AUD_FFMPEGReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_FFMPEGReader::getSpecs() const
-{
- return m_specs.specs;
-}
-
-void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
-{
- // read packages and decode them
- AVPacket packet;
- int data_size = 0;
- int pkgbuf_pos;
- int left = length;
- int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
-
- sample_t* buf = buffer;
- pkgbuf_pos = m_pkgbuf_left;
- m_pkgbuf_left = 0;
-
- // there may still be data in the buffer from the last call
- if(pkgbuf_pos > 0)
- {
- data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
- data_size / AUD_FORMAT_SIZE(m_specs.format));
- buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
- }
-
- // for each frame read as long as there isn't enough data already
- while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
- {
- // is it a frame from the audio stream?
- if(packet.stream_index == m_stream)
- {
- // decode the package
- pkgbuf_pos = decode(packet, m_pkgbuf);
-
- // copy to output buffer
- data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
- data_size / AUD_FORMAT_SIZE(m_specs.format));
- buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
- }
- av_free_packet(&packet);
- }
- // read more data than necessary?
- if(pkgbuf_pos > data_size)
- {
- m_pkgbuf_left = pkgbuf_pos-data_size;
- memmove(m_pkgbuf.getBuffer(),
- ((data_t*)m_pkgbuf.getBuffer())+data_size,
- pkgbuf_pos-data_size);
- }
-
- if((eos = (left > 0)))
- length -= left;
-
- m_position += length;
-}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
deleted file mode 100644
index 377086e2625..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGReader.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGREADER_H__
-#define __AUD_FFMPEGREADER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-struct AVCodecContext;
-extern "C" {
-#include <libavformat/avformat.h>
-}
-
-/**
- * This class reads a sound file via ffmpeg.
- * \warning Seeking may not be accurate! Moreover the position is updated after
- * a buffer reading call. So calling getPosition right after seek
- * normally results in a wrong value.
- */
-class AUD_FFMPEGReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The buffer for package reading.
- */
- AUD_Buffer m_pkgbuf;
-
- /**
- * The count of samples still available from the last read package.
- */
- int m_pkgbuf_left;
-
- /**
- * The AVFormatContext structure for using ffmpeg.
- */
- AVFormatContext* m_formatCtx;
-
- /**
- * The AVCodecContext structure for using ffmpeg.
- */
- AVCodecContext* m_codecCtx;
-
- /**
- * The AVIOContext to read the data from.
- */
- AVIOContext* m_aviocontext;
-
- /**
- * The stream ID in the file.
- */
- int m_stream;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- /**
- * The memory file to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_membuffer;
-
- /**
- * The buffer to read with.
- */
- data_t* m_membuf;
-
- /**
- * Reading position of the buffer.
- */
- int64_t m_membufferpos;
-
- /**
- * Whether the audio data has to be interleaved after reading.
- */
- bool m_tointerleave;
-
- /**
- * Decodes a packet into the given buffer.
- * \param packet The AVPacket to decode.
- * \param buffer The target buffer.
- * \return The count of read bytes.
- */
- int decode(AVPacket& packet, AUD_Buffer& buffer);
-
- /**
- * Initializes the object.
- */
- void init();
-
- // hide copy constructor and operator=
- AUD_FFMPEGReader(const AUD_FFMPEGReader&);
- AUD_FFMPEGReader& operator=(const AUD_FFMPEGReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param filename The path to the file to be read.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with ffmpeg.
- */
- AUD_FFMPEGReader(std::string filename);
-
- /**
- * Creates a new reader.
- * \param buffer The buffer to read from.
- * \exception AUD_Exception Thrown if the buffer specified cannot be read
- * with ffmpeg.
- */
- AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer);
-
- /**
- * Destroys the reader and closes the file.
- */
- virtual ~AUD_FFMPEGReader();
-
- static int read_packet(void* opaque, uint8_t* buf, int buf_size);
- static int64_t seek_packet(void* opaque, int64_t offset, int whence);
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_FFMPEGREADER_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
deleted file mode 100644
index 3f95ac7a4da..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGWriter.h"
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libavformat/avio.h>
-#include "ffmpeg_compat.h"
-}
-
-static const char* context_error = "AUD_FFMPEGWriter: Couldn't allocate context.";
-static const char* codec_error = "AUD_FFMPEGWriter: Invalid codec or codec not found.";
-static const char* stream_error = "AUD_FFMPEGWriter: Couldn't allocate stream.";
-static const char* format_error = "AUD_FFMPEGWriter: Unsupported sample format.";
-static const char* file_error = "AUD_FFMPEGWriter: File couldn't be written.";
-static const char* write_error = "AUD_FFMPEGWriter: Error writing packet.";
-
-AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
- m_position(0),
- m_specs(specs),
- m_input_samples(0)
-{
- static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
-
- m_formatCtx = avformat_alloc_context();
- if (!m_formatCtx) AUD_THROW(AUD_ERROR_FFMPEG, context_error);
-
- strcpy(m_formatCtx->filename, filename.c_str());
- m_outputFmt = m_formatCtx->oformat = av_guess_format(formats[format], filename.c_str(), NULL);
- if (!m_outputFmt) {
- avformat_free_context(m_formatCtx);
- AUD_THROW(AUD_ERROR_FFMPEG, context_error);
- }
-
- switch(codec)
- {
- case AUD_CODEC_AAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
- break;
- case AUD_CODEC_AC3:
- m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
- break;
- case AUD_CODEC_FLAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
- break;
- case AUD_CODEC_MP2:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
- break;
- case AUD_CODEC_MP3:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
- break;
- case AUD_CODEC_PCM:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
- break;
- case AUD_FORMAT_S16:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
- break;
- case AUD_FORMAT_S24:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
- break;
- case AUD_FORMAT_S32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
- break;
- case AUD_FORMAT_FLOAT32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
- break;
- case AUD_FORMAT_FLOAT64:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
- break;
- default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
- break;
- }
- break;
- case AUD_CODEC_VORBIS:
- m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
- break;
- default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
- break;
- }
-
- try
- {
- if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
- AUD_THROW(AUD_ERROR_SPECS, codec_error);
-
- m_stream = avformat_new_stream(m_formatCtx, NULL);
- if(!m_stream)
- AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
-
- m_codecCtx = m_stream->codec;
- m_codecCtx->codec_id = m_outputFmt->audio_codec;
- m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
- m_codecCtx->bit_rate = bitrate;
- m_codecCtx->sample_rate = int(m_specs.rate);
- m_codecCtx->channels = m_specs.channels;
- m_codecCtx->time_base.num = 1;
- m_codecCtx->time_base.den = m_codecCtx->sample_rate;
-
- switch(m_specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_U8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_FLT;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_DBL;
- break;
- default:
- AUD_THROW(AUD_ERROR_FFMPEG, format_error);
- }
-
- try
- {
- if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
- m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
- AVCodec* codec = avcodec_find_encoder(m_codecCtx->codec_id);
- if(!codec)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- if(codec->sample_fmts) {
- // Check if the preferred sample format for this codec is supported.
- const enum AVSampleFormat *p = codec->sample_fmts;
- for(; *p != -1; p++) {
- if(*p == m_stream->codec->sample_fmt)
- break;
- }
- if(*p == -1) {
- // Sample format incompatible with codec. Defaulting to a format known to work.
- m_stream->codec->sample_fmt = codec->sample_fmts[0];
- }
- }
-
- if(avcodec_open2(m_codecCtx, codec, NULL))
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
- int samplesize = AUD_MAX(AUD_SAMPLE_SIZE(m_specs), AUD_DEVICE_SAMPLE_SIZE(m_specs));
-
- if(m_codecCtx->frame_size <= 1) {
- m_input_size = FF_MIN_BUFFER_SIZE * 8 / m_codecCtx->bits_per_coded_sample / m_codecCtx->channels;
- m_input_buffer.resize(m_input_size * samplesize);
- }
- else
- {
- m_input_buffer.resize(m_codecCtx->frame_size * samplesize);
- m_input_size = m_codecCtx->frame_size;
- }
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- m_frame = av_frame_alloc();
- if (!m_frame)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
- av_frame_unref(m_frame);
- m_frame->linesize[0] = m_input_size * samplesize;
- m_frame->format = m_codecCtx->sample_fmt;
- m_frame->nb_samples = m_input_size;
-# ifdef FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
- m_frame->sample_rate = m_codecCtx->sample_rate;
-# endif
-# ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
- m_frame->channel_layout = m_codecCtx->channel_layout;
-# endif
- m_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt);
- m_frame_pts = 0;
- m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
- if(m_deinterleave)
- m_deinterleave_buffer.resize(m_input_size * m_codecCtx->channels * m_sample_size);
-#endif
-
- try
- {
- if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
- AUD_THROW(AUD_ERROR_FILE, file_error);
-
- if(avformat_write_header(m_formatCtx, NULL) < 0) {
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- avcodec_close(m_codecCtx);
- av_freep(&m_formatCtx->streams[0]->codec);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- av_freep(&m_formatCtx->streams[0]);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- av_free(m_formatCtx);
- throw;
- }
-}
-
-AUD_FFMPEGWriter::~AUD_FFMPEGWriter()
-{
- // writte missing data
- if(m_input_samples)
- {
- sample_t* buf = m_input_buffer.getBuffer();
- memset(buf + m_specs.channels * m_input_samples, 0,
- (m_input_size - m_input_samples) * AUD_DEVICE_SAMPLE_SIZE(m_specs));
-
- encode(buf);
- }
-
- av_write_trailer(m_formatCtx);
-
- avcodec_close(m_codecCtx);
-
- av_freep(&m_formatCtx->streams[0]->codec);
- av_freep(&m_formatCtx->streams[0]);
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- av_frame_free(&m_frame);
-#endif
-
- avio_close(m_formatCtx->pb);
- av_free(m_formatCtx);
-}
-
-int AUD_FFMPEGWriter::getPosition() const
-{
- return m_position;
-}
-
-AUD_DeviceSpecs AUD_FFMPEGWriter::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_FFMPEGWriter::encode(sample_t* data)
-{
- // convert first
- if(m_input_size)
- m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_size * m_specs.channels);
-
- AVPacket packet = { 0 };
- av_init_packet(&packet);
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- int got_output, ret;
- m_frame->pts = m_frame_pts / av_q2d(m_codecCtx->time_base);
- m_frame_pts++;
-#ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
- m_frame->channel_layout = m_codecCtx->channel_layout;
-#endif
-
- if(m_deinterleave) {
- for(int channel = 0; channel < m_codecCtx->channels; channel++) {
- for(int i = 0; i < m_frame->nb_samples; i++) {
- memcpy(reinterpret_cast<uint8_t*>(m_deinterleave_buffer.getBuffer()) + (i + channel * m_frame->nb_samples) * m_sample_size,
- reinterpret_cast<uint8_t*>(data) + (m_codecCtx->channels * i + channel) * m_sample_size, m_sample_size);
- }
- }
-
- data = m_deinterleave_buffer.getBuffer();
- }
-
- avcodec_fill_audio_frame(m_frame, m_codecCtx->channels, m_codecCtx->sample_fmt, reinterpret_cast<uint8_t*>(data),
- m_frame->nb_samples * av_get_bytes_per_sample(m_codecCtx->sample_fmt) * m_codecCtx->channels, 1);
-
- ret = avcodec_encode_audio2(m_codecCtx, &packet, m_frame, &got_output);
- if(ret < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- if(!got_output)
- return;
-#else
- sample_t* outbuf = m_output_buffer.getBuffer();
-
- packet.size = avcodec_encode_audio(m_codecCtx, reinterpret_cast<uint8_t*>(outbuf), m_output_buffer.getSize(), reinterpret_cast<short*>(data));
- if(m_codecCtx->coded_frame && m_codecCtx->coded_frame->pts != AV_NOPTS_VALUE)
- packet.pts = av_rescale_q(m_codecCtx->coded_frame->pts, m_codecCtx->time_base, m_stream->time_base);
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.data = reinterpret_cast<uint8_t*>(outbuf);
-#endif
-
- if(packet.pts != AV_NOPTS_VALUE)
- packet.pts = av_rescale_q(packet.pts, m_codecCtx->time_base, m_stream->time_base);
- if(packet.dts != AV_NOPTS_VALUE)
- packet.dts = av_rescale_q(packet.dts, m_codecCtx->time_base, m_stream->time_base);
- if(packet.duration > 0)
- packet.duration = av_rescale_q(packet.duration, m_codecCtx->time_base, m_stream->time_base);
-
- packet.stream_index = m_stream->index;
-
- packet.flags |= AV_PKT_FLAG_KEY;
-
- if(av_interleaved_write_frame(m_formatCtx, &packet)) {
- av_free_packet(&packet);
- AUD_THROW(AUD_ERROR_FFMPEG, write_error);
- }
-
- av_free_packet(&packet);
-}
-
-void AUD_FFMPEGWriter::write(unsigned int length, sample_t* buffer)
-{
- unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
-
- if(m_input_size)
- {
- sample_t* inbuf = m_input_buffer.getBuffer();
-
- while(length)
- {
- unsigned int len = AUD_MIN(m_input_size - m_input_samples, length);
-
- memcpy(inbuf + m_input_samples * m_specs.channels, buffer, len * samplesize);
-
- buffer += len * m_specs.channels;
- m_input_samples += len;
- m_position += len;
- length -= len;
-
- if(m_input_samples == m_input_size)
- {
- encode(inbuf);
-
- m_input_samples = 0;
- }
- }
- }
- else // PCM data, can write directly!
- {
- int samplesize = AUD_SAMPLE_SIZE(m_specs);
- if(m_output_buffer.getSize() != length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8)
- m_output_buffer.resize(length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8);
- m_input_buffer.assureSize(length * AUD_MAX(AUD_DEVICE_SAMPLE_SIZE(m_specs), samplesize));
-
- sample_t* buf = m_input_buffer.getBuffer();
- m_convert(reinterpret_cast<data_t*>(buf), reinterpret_cast<data_t*>(buffer), length * m_specs.channels);
-
- encode(buf);
-
- m_position += length;
- }
-}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
deleted file mode 100644
index 492aa35ff12..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/ffmpeg/AUD_FFMPEGWriter.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGWRITER_H__
-#define __AUD_FFMPEGWRITER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-#include "AUD_IWriter.h"
-
-#include <string>
-
-struct AVCodecContext;
-extern "C" {
-#include <libavformat/avformat.h>
-}
-
-/**
- * This class writes a sound file via ffmpeg.
- */
-class AUD_FFMPEGWriter : public AUD_IWriter
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The AVFormatContext structure for using ffmpeg.
- */
- AVFormatContext* m_formatCtx;
-
- /**
- * The AVCodecContext structure for using ffmpeg.
- */
- AVCodecContext* m_codecCtx;
-
- /**
- * The AVOutputFormat structure for using ffmpeg.
- */
- AVOutputFormat* m_outputFmt;
-
- /**
- * The AVStream structure for using ffmpeg.
- */
- AVStream* m_stream;
-
- /**
- * Frame sent to the encoder.
- */
- AVFrame *m_frame;
-
- /**
- * PTS of next frame to write.
- */
- int m_frame_pts;
-
- /**
- * Number of bytes per sample.
- */
- int m_sample_size;
-
- /**
- * Need to de-interleave audio for planar sample formats.
- */
- bool m_deinterleave;
-
- AUD_Buffer m_deinterleave_buffer;
-
- /**
- * The input buffer for the format converted data before encoding.
- */
- AUD_Buffer m_input_buffer;
-
- /**
- * The output buffer for the encoded audio data.
- */
- AUD_Buffer m_output_buffer;
-
- /**
- * The count of input samples we have so far.
- */
- unsigned int m_input_samples;
-
- /**
- * The count of input samples necessary to encode a packet.
- */
- unsigned int m_input_size;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- // hide copy constructor and operator=
- AUD_FFMPEGWriter(const AUD_FFMPEGWriter&);
- AUD_FFMPEGWriter& operator=(const AUD_FFMPEGWriter&);
-
- /**
- * Encodes to the output buffer.
- * \param data Pointer to the data to encode.
- */
- void encode(sample_t* data);
-
-public:
- /**
- * Creates a new writer.
- * \param filename The path to the file to be read.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with ffmpeg.
- */
- AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
-
- /**
- * Destroys the writer and closes the file.
- */
- virtual ~AUD_FFMPEGWriter();
-
- virtual int getPosition() const;
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual void write(unsigned int length, sample_t* buffer);
-};
-
-#endif //__AUD_FFMPEGWRITER_H__
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.cpp b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
deleted file mode 100644
index 1e6538d80de..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassFactory.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/fftw/AUD_BandPassFactory.cpp
- * \ingroup audfftw
- */
-
-
-#include "AUD_BandPassFactory.h"
-#include "AUD_BandPassReader.h"
-
-AUD_BandPassFactory::AUD_BandPassFactory(AUD_IFactory* factory, float low,
- float high) :
- AUD_EffectFactory(factory),
- m_low(low),
- m_high(high) {}
-
-AUD_BandPassFactory::AUD_BandPassFactory(float low, float high) :
- AUD_EffectFactory(0),
- m_low(low),
- m_high(high) {}
-
-float AUD_BandPassFactory::getLow()
-{
- return m_low;
-}
-
-float AUD_BandPassFactory::getHigh()
-{
- return m_high;
-}
-
-void AUD_BandPassFactory::setLow(float low)
-{
- m_low = low;
-}
-
-void AUD_BandPassFactory::setHigh(float high)
-{
- m_high = high;
-}
-
-AUD_IReader* AUD_BandPassFactory::createReader()
-{
- AUD_IReader* reader = getReader();
-
- if(reader != 0)
- {
- reader = new AUD_BandPassReader(reader, m_low, m_high);
- AUD_NEW("reader")
- }
-
- return reader;
-}
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.h b/intern/audaspace/fftw/AUD_BandPassFactory.h
deleted file mode 100644
index 90b090dce16..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassFactory.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/fftw/AUD_BandPassFactory.h
- * \ingroup audfftw
- */
-
-
-#ifndef __AUD_BANDPASSFACTORY_H__
-#define __AUD_BANDPASSFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory creates a band pass filter for a sound wave.
- */
-class AUD_BandPassFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The lowest frequency to be passed.
- */
- float m_low;
-
- /**
- * The highest frequency to be passed.
- */
- float m_high;
-
-public:
- /**
- * Creates a new band pass factory.
- * \param factory The input factory.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassFactory(AUD_IFactory* factory, float low, float high);
-
- /**
- * Creates a new band pass factory.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassFactory(float low, float high);
-
- /**
- * Returns the lowest passed frequency.
- */
- float getLow();
-
- /**
- * Returns the highest passed frequency.
- */
- float getHigh();
-
- /**
- * Sets the lowest passed frequency.
- * \param low The lowest passed frequency.
- */
- void setLow(float low);
-
- /**
- * Sets the highest passed frequency.
- * \param high The highest passed frequency.
- */
- void setHigh(float high);
-
- virtual AUD_IReader* createReader();
-};
-
-#endif //__AUD_BANDPASSFACTORY_H__
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.cpp b/intern/audaspace/fftw/AUD_BandPassReader.cpp
deleted file mode 100644
index 7e181fb499d..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassReader.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/fftw/AUD_BandPassReader.cpp
- * \ingroup audfftw
- */
-
-
-#include "AUD_BandPassReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-#include <stdio.h>
-
-AUD_BandPassReader::AUD_BandPassReader(AUD_IReader* reader, float low,
- float high) :
- AUD_EffectReader(reader), m_low(low), m_high(high)
-{
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_in = new AUD_Buffer(); AUD_NEW("buffer")
- m_out = new AUD_Buffer(); AUD_NEW("buffer")
- m_length = 0;
-}
-
-AUD_BandPassReader::~AUD_BandPassReader()
-{
- if(m_length != 0)
- {
- fftw_destroy_plan(m_forward);
- fftw_destroy_plan(m_backward);
- }
-
- delete m_buffer; AUD_DELETE("buffer")
- delete m_in; AUD_DELETE("buffer")
- delete m_out; AUD_DELETE("buffer")
-}
-
-AUD_ReaderType AUD_BandPassReader::getType()
-{
- return m_reader->getType();
-}
-
-void AUD_BandPassReader::read(int & length, sample_t* & buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
-
- m_reader->read(length, buffer);
-
- if(length > 0)
- {
- m_buffer->assureSize(length * AUD_SAMPLE_SIZE(specs));
-
- if(length != m_length)
- {
- if(m_length != 0)
- {
- fftw_destroy_plan(m_forward);
- fftw_destroy_plan(m_backward);
- }
-
- m_length = length;
-
- if(m_length * sizeof(double) > m_in->getSize())
- {
- m_in->resize(m_length * sizeof(double));
- m_out->resize((m_length / 2 + 1) * sizeof(fftw_complex));
- }
-
- m_forward = fftw_plan_dft_r2c_1d(m_length,
- (double*)m_in->getBuffer(),
- (fftw_complex*)m_out->getBuffer(),
- FFTW_ESTIMATE);
- m_backward = fftw_plan_dft_c2r_1d(m_length,
- (fftw_complex*)m_out->getBuffer(),
- (double*)m_in->getBuffer(),
- FFTW_ESTIMATE);
- }
-
- double* target = (double*) m_in->getBuffer();
- sample_t* target2 = m_buffer->getBuffer();
- fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
- float frequency;
-
- for(int channel = 0; channel < specs.channels; channel++)
- {
- for(int i = 0; i < m_length; i++)
- target[i] = buffer[i * specs.channels + channel];
-
- fftw_execute(m_forward);
-
- for(int i = 0; i < m_length / 2 + 1; i++)
- {
- frequency = i * specs.rate / (m_length / 2.0f + 1.0f);
- if((frequency < m_low) || (frequency > m_high))
- complex[i][0] = complex[i][1] = 0.0;
- }
-
- fftw_execute(m_backward);
-
- for(int i = 0; i < m_length; i++)
- target2[i * specs.channels + channel] = target[i] / m_length;
- }
- }
-
- buffer = m_buffer->getBuffer();
-}
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.h b/intern/audaspace/fftw/AUD_BandPassReader.h
deleted file mode 100644
index 55a950818e0..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassReader.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/fftw/AUD_BandPassReader.h
- * \ingroup audfftw
- */
-
-
-#ifndef __AUD_BANDPASSREADER_H__
-#define __AUD_BANDPASSREADER_H__
-
-#include <fftw3.h>
-
-#include "AUD_EffectReader.h"
-class AUD_Buffer;
-
-/**
- * This class only passes a specific frequency band of another reader.
- */
-class AUD_BandPassReader : public AUD_EffectReader
-{
-private:
- /**
- * The playback buffer.
- */
- AUD_Buffer *m_buffer;
-
- /**
- * The input buffer for fourier transformations.
- */
- AUD_Buffer *m_in;
-
- /**
- * The output buffer for fourier transformations.
- */
- AUD_Buffer *m_out;
-
- /**
- * The lowest passed frequency.
- */
- float m_low;
-
- /**
- * The highest passed frequency.
- */
- float m_high;
-
- /**
- * The fftw plan for forward transformation.
- */
- fftw_plan m_forward;
-
- /**
- * The fftw plan for backward transformation.
- */
- fftw_plan m_backward;
-
- /**
- * The length of the plans.
- */
- int m_length;
-
-public:
- /**
- * Creates a new band pass reader.
- * \param reader The reader to read from.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassReader(AUD_IReader* reader, float low, float high);
-
- /**
- * Destroys the reader.
- */
- virtual ~AUD_BandPassReader();
-
- virtual AUD_ReaderType getType();
- virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //__AUD_BANDPASSREADER_H__
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
deleted file mode 100644
index e0bc18ea520..00000000000
--- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_AnimateableProperty.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_AnimateableProperty.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <cmath>
-
-AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
- AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
-{
- memset(getBuffer(), 0, count * sizeof(float));
-
- 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_AnimateableProperty::AUD_AnimateableProperty(int count, float value) :
- AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
-{
- sample_t* buf = getBuffer();
-
- for(int i = 0; i < count; i++)
- buf[i] = value;
-
- 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);
-}
-
-void AUD_AnimateableProperty::updateUnknownCache(int start, int end)
-{
- float* buf = getBuffer();
-
- for(int i = start; i <= end; i++)
- // TODO: maybe first instead of zero order interpolation?
- memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
-}
-
-AUD_AnimateableProperty::~AUD_AnimateableProperty()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_AnimateableProperty::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_AnimateableProperty::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-void AUD_AnimateableProperty::write(const float* data)
-{
- AUD_MutexLock lock(*this);
-
- m_isAnimated = false;
- m_unknown.clear();
- memcpy(getBuffer(), data, m_count * sizeof(float));
-}
-
-void AUD_AnimateableProperty::write(const float* data, int position, int count)
-{
- AUD_MutexLock lock(*this);
-
- int pos = getSize() / (sizeof(float) * m_count);
-
- if(!m_isAnimated)
- pos = 0;
-
- m_isAnimated = true;
-
- assureSize((count + position) * m_count * sizeof(float), true);
-
- float* buf = getBuffer();
-
- memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
-
- // have to fill up space between?
- if(pos < position)
- {
- m_unknown.push_back(Unknown(pos, position - 1));
-
- // if the buffer was not animated before, we copy the previous static value
- if(pos == 0)
- pos = 1;
-
- updateUnknownCache(pos, position - 1);
- }
- // otherwise it's not at the end, let's check if some unknown part got filled
- else
- {
- bool erased = false;
-
- for(std::list<Unknown>::iterator it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++)
- {
- erased = false;
-
- // unknown area before position
- if(it->end < position)
- continue;
-
- // we're after the new area, let's stop
- if(it->start >= position + count)
- break;
-
- // we have an intersection, now 4 cases:
- // the start is included
- if(position <= it->start)
- {
- // the end is included
- if(position + count > it->end)
- {
- // simply delete
- it = m_unknown.erase(it);
- erased = true;
- }
- // the end is excluded, a second part remains
- else
- {
- // update second part
- it->start = position + count;
- updateUnknownCache(it->start, it->end);
- break;
- }
- }
- // start is excluded, a first part remains
- else
- {
- // the end is included
- if(position + count > it->end)
- {
- // update first part
- it->end = position - 1;
- }
- // the end is excluded, a second part remains
- else
- {
- // add another item and update both parts
- m_unknown.insert(it, Unknown(it->start, position - 1));
- it->start = position + count;
- updateUnknownCache(it->start, it->end);
- }
- }
- }
- }
-}
-
-void AUD_AnimateableProperty::read(float position, float* out)
-{
- AUD_MutexLock lock(*this);
-
- if(!m_isAnimated)
- {
- memcpy(out, getBuffer(), m_count * sizeof(float));
- return;
- }
-
- int last = getSize() / (sizeof(float) * m_count) - 1;
- float t = position - floor(position);
-
- if(position >= last)
- {
- position = last;
- t = 0;
- }
-
- if(t == 0)
- {
- memcpy(out, getBuffer() + int(floor(position)) * m_count, m_count * sizeof(float));
- }
- else
- {
- int pos = int(floor(position)) * m_count;
- float t2 = t * t;
- float t3 = t2 * t;
- float m0, m1;
- float* p0;
- float* p1 = getBuffer() + pos;
- float* p2;
- float* p3;
- last *= m_count;
-
- if(pos == 0)
- p0 = p1;
- else
- p0 = p1 - m_count;
-
- p2 = p1 + m_count;
- if(pos + m_count == last)
- p3 = p2;
- else
- p3 = p2 + m_count;
-
- for(int i = 0; i < m_count; i++)
- {
- m0 = (p2[i] - p0[i]) / 2.0f;
- m1 = (p3[i] - p1[i]) / 2.0f;
-
- out[i] = (2 * t3 - 3 * t2 + 1) * p0[i] + (-2 * t3 + 3 * t2) * p1[i] +
- (t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
- }
- }
-}
-
-bool AUD_AnimateableProperty::isAnimated() const
-{
- return m_isAnimated;
-}
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h
deleted file mode 100644
index f07e5916b25..00000000000
--- a/intern/audaspace/intern/AUD_AnimateableProperty.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_AnimateableProperty.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_ANIMATEABLEPROPERTY_H__
-#define __AUD_ANIMATEABLEPROPERTY_H__
-
-#include "AUD_Buffer.h"
-#include "AUD_ILockable.h"
-
-#include <pthread.h>
-#include <list>
-
-/**
- * This class saves animation data for float properties.
- */
-class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable
-{
-private:
- struct Unknown {
- int start;
- int end;
-
- Unknown(int start, int end) :
- start(start), end(end) {}
- };
-
- /// The count of floats for a single property.
- const int m_count;
-
- /// Whether the property is animated or not.
- bool m_isAnimated;
-
- /// The mutex for locking.
- pthread_mutex_t m_mutex;
-
- /// The list of unknown buffer areas.
- std::list<Unknown> m_unknown;
-
- // hide copy constructor and operator=
- AUD_AnimateableProperty(const AUD_AnimateableProperty&);
- AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&);
-
- void updateUnknownCache(int start, int end);
-
-public:
- /**
- * Creates a new animateable property.
- * \param count The count of floats for a single property.
- */
- AUD_AnimateableProperty(int count = 1);
-
- /**
- * Creates a new animateable property.
- * \param count The count of floats for a single property.
- * \param count The value that the property should get initialized with. All count floats will be initialized to the same value.
- */
- AUD_AnimateableProperty(int count, float value);
-
- /**
- * Destroys the animateable property.
- */
- ~AUD_AnimateableProperty();
-
- /**
- * Locks the property.
- */
- virtual void lock();
-
- /**
- * Unlocks the previously locked property.
- */
- virtual void unlock();
-
- /**
- * Writes the properties value and marks it non-animated.
- * \param data The new value.
- */
- void write(const float* data);
-
- /**
- * Writes the properties value and marks it animated.
- * \param data The new value.
- * \param position The position in the animation in frames.
- * \param count The count of frames to write.
- */
- void write(const float* data, int position, int count);
-
- /**
- * Reads the properties value.
- * \param position The position in the animation in frames.
- * \param[out] out Where to write the value to.
- */
- void read(float position, float* out);
-
- /**
- * Returns whether the property is animated.
- * \return Whether the property is animated.
- */
- bool isAnimated() const;
-};
-
-#endif //__AUD_ANIMATEABLEPROPERTY_H__
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
deleted file mode 100644
index b7157f672b4..00000000000
--- a/intern/audaspace/intern/AUD_Buffer.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Buffer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_Buffer.h"
-#include "AUD_Space.h"
-
-#include <cstring>
-#include <cstdlib>
-
-#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
-
-AUD_Buffer::AUD_Buffer(int size)
-{
- m_size = size;
- m_buffer = (data_t*) malloc(size+16);
-}
-
-AUD_Buffer::~AUD_Buffer()
-{
- free(m_buffer);
-}
-
-sample_t* AUD_Buffer::getBuffer() const
-{
- return (sample_t*) AUD_ALIGN(m_buffer);
-}
-
-int AUD_Buffer::getSize() const
-{
- return m_size;
-}
-
-void AUD_Buffer::resize(int size, bool keep)
-{
- if(keep)
- {
- data_t* buffer = (data_t*) malloc(size + 16);
-
- memcpy(AUD_ALIGN(buffer), AUD_ALIGN(m_buffer), AUD_MIN(size, m_size));
-
- free(m_buffer);
- m_buffer = buffer;
- }
- else
- m_buffer = (data_t*) realloc(m_buffer, size + 16);
-
- m_size = size;
-}
-
-void AUD_Buffer::assureSize(int size, bool keep)
-{
- if(m_size < size)
- resize(size, keep);
-}
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
deleted file mode 100644
index d3207f04f83..00000000000
--- a/intern/audaspace/intern/AUD_Buffer.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Buffer.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_BUFFER_H__
-#define __AUD_BUFFER_H__
-
-#include "AUD_Space.h"
-
-/**
- * This class is a simple buffer in RAM which is 16 Byte aligned and provides
- * resize functionality.
- */
-class AUD_Buffer
-{
-private:
- /// The size of the buffer in bytes.
- int m_size;
-
- /// The pointer to the buffer memory.
- data_t* m_buffer;
-
- // hide copy constructor and operator=
- AUD_Buffer(const AUD_Buffer&);
- AUD_Buffer& operator=(const AUD_Buffer&);
-
-public:
- /**
- * Creates a new buffer.
- * \param size The size of the buffer in bytes.
- */
- AUD_Buffer(int size = 0);
-
- /**
- * Destroys the buffer.
- */
- ~AUD_Buffer();
-
- /**
- * Returns the pointer to the buffer in memory.
- */
- sample_t* getBuffer() const;
-
- /**
- * Returns the size of the buffer in bytes.
- */
- int getSize() const;
-
- /**
- * Resizes the buffer.
- * \param size The new size of the buffer, measured in bytes.
- * \param keep Whether to keep the old data. If the new buffer is smaller,
- * the data at the end will be lost.
- */
- void resize(int size, bool keep = false);
-
- /**
- * Makes sure the buffer has a minimum size.
- * If size is >= current size, nothing will happen.
- * Otherwise the buffer is resized with keep as parameter.
- * \param size The new minimum size of the buffer, measured in bytes.
- * \param keep Whether to keep the old data. If the new buffer is smaller,
- * the data at the end will be lost.
- */
- void assureSize(int size, bool keep = false);
-};
-
-#endif //__AUD_BUFFER_H__
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
deleted file mode 100644
index b9d819ff774..00000000000
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_BufferReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_BufferReader.h"
-#include "AUD_Buffer.h"
-#include "AUD_Space.h"
-
-#include <cstring>
-
-AUD_BufferReader::AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer,
- AUD_Specs specs) :
- m_position(0), m_buffer(buffer), m_specs(specs)
-{
-}
-
-bool AUD_BufferReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_BufferReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_BufferReader::getLength() const
-{
- return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
-}
-
-int AUD_BufferReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_BufferReader::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer)
-{
- eos = false;
-
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
-
- sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;
-
- // in case the end of the buffer is reached
- if(m_buffer->getSize() < (m_position + length) * sample_size)
- {
- length = m_buffer->getSize() / sample_size - m_position;
- eos = true;
- }
-
- if(length < 0)
- {
- length = 0;
- return;
- }
-
- m_position += length;
- memcpy(buffer, buf, length * sample_size);
-}
diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h
deleted file mode 100644
index d0c90ce7e61..00000000000
--- a/intern/audaspace/intern/AUD_BufferReader.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_BufferReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_BUFFERREADER_H__
-#define __AUD_BUFFERREADER_H__
-
-#include "AUD_IReader.h"
-class AUD_Buffer;
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This class represents a simple reader from a buffer that exists in memory.
- * \warning Notice that the buffer used for creating the reader must exist as
- * long as the reader exists.
- */
-class AUD_BufferReader : public AUD_IReader
-{
-private:
- /**
- * The current position in the buffer.
- */
- int m_position;
-
- /**
- * The buffer that is read.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- /**
- * The specification of the sample data in the buffer.
- */
- AUD_Specs m_specs;
-
- // hide copy constructor and operator=
- AUD_BufferReader(const AUD_BufferReader&);
- AUD_BufferReader& operator=(const AUD_BufferReader&);
-
-public:
- /**
- * Creates a new buffer reader.
- * \param buffer The buffer to read from.
- * \param specs The specification of the sample data in the buffer.
- */
- AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer, AUD_Specs specs);
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_BUFFERREADER_H__
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
deleted file mode 100644
index 52cf256147f..00000000000
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ /dev/null
@@ -1,1323 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_C-API.cpp
- * \ingroup audaspaceintern
- */
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-// quiet unudef define warning
-#ifdef __STDC_CONSTANT_MACROS
-// pass
-#endif
-
-#ifdef WITH_PYTHON
-# include "AUD_PyInit.h"
-# include "AUD_PyAPI.h"
-#endif
-
-#include <cstdlib>
-#include <cstring>
-#include <cmath>
-#include <sstream>
-#include <iostream>
-
-#include "AUD_NULLDevice.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_FileFactory.h"
-#include "AUD_FileWriter.h"
-#include "AUD_StreamBufferFactory.h"
-#include "AUD_DelayFactory.h"
-#include "AUD_LimiterFactory.h"
-#include "AUD_PingPongFactory.h"
-#include "AUD_LoopFactory.h"
-#include "AUD_RectifyFactory.h"
-#include "AUD_EnvelopeFactory.h"
-#include "AUD_LinearResampleFactory.h"
-#include "AUD_LowpassFactory.h"
-#include "AUD_HighpassFactory.h"
-#include "AUD_AccumulatorFactory.h"
-#include "AUD_SumFactory.h"
-#include "AUD_SquareFactory.h"
-#include "AUD_ChannelMapperFactory.h"
-#include "AUD_Buffer.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_IReader.h"
-#include "AUD_SequencerFactory.h"
-#include "AUD_SequencerEntry.h"
-#include "AUD_SilenceFactory.h"
-#include "AUD_MutexLock.h"
-
-#ifdef WITH_SDL
-#include "AUD_SDLDevice.h"
-#endif
-
-#ifdef WITH_OPENAL
-#include "AUD_OpenALDevice.h"
-#endif
-
-#ifdef WITH_JACK
-#include "AUD_JackDevice.h"
-#include "AUD_JackLibrary.h"
-#endif
-
-
-#ifdef WITH_FFMPEG
-extern "C" {
-#include <libavformat/avformat.h>
-}
-#endif
-
-#include <cassert>
-
-typedef boost::shared_ptr<AUD_IFactory> AUD_Sound;
-typedef boost::shared_ptr<AUD_IDevice> AUD_Device;
-typedef boost::shared_ptr<AUD_IHandle> AUD_Handle;
-typedef boost::shared_ptr<AUD_SequencerEntry> AUD_SEntry;
-
-#define AUD_CAPI_IMPLEMENTATION
-#include "AUD_C-API.h"
-
-#ifndef NULL
-# define NULL (void *)0
-#endif
-
-static boost::shared_ptr<AUD_IDevice> AUD_device;
-static AUD_I3DDevice *AUD_3ddevice;
-
-void AUD_initOnce()
-{
-#ifdef WITH_FFMPEG
- av_register_all();
-#endif
-#ifdef WITH_JACK
- AUD_jack_init();
-#endif
-}
-
-void AUD_exitOnce()
-{
-#ifdef WITH_JACK
- AUD_jack_exit();
-#endif
-}
-
-AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
-{
- boost::shared_ptr<AUD_IDevice> dev;
-
- if (AUD_device.get()) {
- AUD_exit(NULL);
- }
-
- std::string dname = device;
-
- try {
- if(dname == "Null") {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
- }
-#ifdef WITH_SDL
- else if(dname == "SDL")
- {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
- }
-#endif
-#ifdef WITH_OPENAL
- else if(dname == "OpenAL")
- {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
- }
-#endif
-#ifdef WITH_JACK
- else if(dname == "JACK")
- {
-#ifdef __APPLE__
- struct stat st;
- if (stat("/Library/Frameworks/Jackmp.framework", &st) != 0) {
- printf("Warning: JACK Framework not installed\n");
- return NULL;
- }
- else
-#endif
- if (!AUD_jack_supported()) {
- printf("Warning: JACK cllient not installed\n");
- return NULL;
- }
- else {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
- }
- }
-#endif
- else
- {
- return NULL;
- }
-
- AUD_device = dev;
- AUD_3ddevice = dynamic_cast<AUD_I3DDevice *>(AUD_device.get());
-
- return (AUD_Device*)1;
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-void AUD_exit(AUD_Device* device)
-{
- AUD_device = boost::shared_ptr<AUD_IDevice>();
- AUD_3ddevice = NULL;
-}
-
-#ifdef WITH_PYTHON
-static PyObject *AUD_getCDevice(PyObject *self)
-{
- if (AUD_device.get()) {
- Device *device = (Device *)Device_empty();
- if (device != NULL) {
- device->device = new boost::shared_ptr<AUD_IDevice>(AUD_device);
- return (PyObject *)device;
- }
- }
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef meth_getcdevice[] = {
- {"device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
- "device()\n\n"
- "Returns the application's :class:`Device`.\n\n"
- ":return: The application's :class:`Device`.\n"
- ":rtype: :class:`Device`"}
-};
-
-extern "C" {
-extern void *BKE_sound_get_factory(void *sound);
-}
-
-static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
-{
- long int lptr;
-
- if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
- if (lptr) {
- boost::shared_ptr<AUD_IFactory>* factory = (boost::shared_ptr<AUD_IFactory>*) BKE_sound_get_factory((void *) lptr);
-
- if (factory) {
- Factory *obj = (Factory *)Factory_empty();
- if (obj) {
- obj->factory = new boost::shared_ptr<AUD_IFactory>(*factory);
- return (PyObject *) obj;
- }
- }
- }
- }
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef meth_sound_from_pointer[] = {
- {"_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
- "_sound_from_pointer(pointer)\n\n"
- "Returns the corresponding :class:`Factory` object.\n\n"
- ":arg pointer: The pointer to the bSound object as long.\n"
- ":type pointer: long\n"
- ":return: The corresponding :class:`Factory` object.\n"
- ":rtype: :class:`Factory`"}
-};
-
-PyObject *AUD_initPython()
-{
- PyObject *module = PyInit_aud();
- PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
- PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
- PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
-
- return module;
-}
-
-void *AUD_getPythonSound(AUD_Sound *sound)
-{
- if (sound) {
- Factory *obj = (Factory *) Factory_empty();
- if (obj) {
- obj->factory = new boost::shared_ptr<AUD_IFactory>(*sound);
- return (PyObject *) obj;
- }
- }
-
- return NULL;
-}
-
-AUD_Sound *AUD_getSoundFromPython(void *sound)
-{
- Factory *factory = checkFactory((PyObject *)sound);
-
- if (!factory)
- return NULL;
-
- return new boost::shared_ptr<AUD_IFactory>(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(factory->factory));
-}
-
-#endif
-
-void AUD_Device_lock(AUD_Device* device)
-{
- AUD_device->lock();
-}
-
-void AUD_Device_unlock(AUD_Device* device)
-{
- AUD_device->unlock();
-}
-
-AUD_Channels AUD_Device_getChannels(AUD_Device* device)
-{
- return AUD_device->getSpecs().channels;
-}
-
-AUD_SampleRate AUD_Device_getRate(AUD_Device* device)
-{
- return AUD_device->getSpecs().rate;
-}
-
-AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
-{
- assert(sound);
-
- AUD_SoundInfo info;
- info.specs.channels = AUD_CHANNELS_INVALID;
- info.specs.rate = AUD_RATE_INVALID;
- info.length = 0.0f;
-
- try {
- boost::shared_ptr<AUD_IReader> reader = (*sound)->createReader();
-
- if (reader.get()) {
- info.specs = reader->getSpecs();
- info.length = reader->getLength() / (float) info.specs.rate;
- }
- }
- catch(AUD_Exception &ae)
- {
- std::cout << ae.str << std::endl;
- }
-
- return info;
-}
-
-AUD_Sound *AUD_Sound_file(const char *filename)
-{
- assert(filename);
- return new AUD_Sound(new AUD_FileFactory(filename));
-}
-
-AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size)
-{
- assert(buffer);
- return new AUD_Sound(new AUD_FileFactory(buffer, size));
-}
-
-AUD_Sound *AUD_Sound_cache(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels)
-{
- assert(sound);
-
- try {
- AUD_DeviceSpecs specs;
- specs.channels = channels;
- specs.rate = AUD_RATE_INVALID;
- specs.format = AUD_FORMAT_INVALID;
- return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_PingPongFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_loop(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_LoopFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops)
-{
- assert(handle);
-
- try {
- return (*handle)->setLoopCount(loops);
- }
- catch(AUD_Exception&)
- {
- }
-
- return false;
-}
-
-AUD_Sound *AUD_rectifySound(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_RectifyFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-void AUD_Sound_free(AUD_Sound *sound)
-{
- assert(sound);
- delete sound;
-}
-
-AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep)
-{
- assert(sound);
- try {
- AUD_Handle handle = AUD_device->play(*sound, keep);
- if (handle.get()) {
- return new AUD_Handle(handle);
- }
- }
- catch(AUD_Exception&)
- {
- }
- return NULL;
-}
-
-int AUD_Handle_pause(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->pause();
-}
-
-int AUD_Handle_resume(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->resume();
-}
-
-int AUD_Handle_stop(AUD_Handle *handle)
-{
- assert(handle);
- int result = (*handle)->stop();
- delete handle;
- return result;
-}
-
-void AUD_Device_stopAll(void* device)
-{
- AUD_device->stopAll();
-}
-
-int AUD_Handle_setKeep(AUD_Handle *handle, int keep)
-{
- assert(handle);
- return (*handle)->setKeep(keep);
-}
-
-int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo)
-{
- assert(handle);
- return (*handle)->seek(seekTo);
-}
-
-float AUD_Handle_getPosition(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->getPosition();
-}
-
-AUD_Status AUD_Handle_getStatus(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->getStatus();
-}
-
-int AUD_Device_setListenerLocation(const float location[3])
-{
- if (AUD_3ddevice) {
- AUD_Vector3 v(location[0], location[1], location[2]);
- AUD_3ddevice->setListenerLocation(v);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setListenerVelocity(const float velocity[3])
-{
- if (AUD_3ddevice) {
- AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- AUD_3ddevice->setListenerVelocity(v);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setListenerOrientation(const float orientation[4])
-{
- if (AUD_3ddevice) {
- AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- AUD_3ddevice->setListenerOrientation(q);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setSpeedOfSound(void* device, float speed)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setSpeedOfSound(speed);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setDopplerFactor(void* device, float factor)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setDopplerFactor(factor);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setDistanceModel(model);
- return true;
- }
-
- return false;
-}
-
-int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Vector3 v(location[0], location[1], location[2]);
- return h->setSourceLocation(v);
- }
-
- return false;
-}
-
-int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- return h->setSourceVelocity(v);
- }
-
- return false;
-}
-
-int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- return h->setSourceOrientation(q);
- }
-
- return false;
-}
-
-int AUD_Handle_setRelative(AUD_Handle *handle, int relative)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setRelative(relative);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setVolumeMaximum(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setVolumeMinimum(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setDistanceMaximum(distance);
- }
-
- return false;
-}
-
-int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setDistanceReference(distance);
- }
-
- return false;
-}
-
-int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setAttenuation(factor);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeAngleOuter(angle);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeAngleInner(angle);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeVolumeOuter(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolume(AUD_Handle *handle, float volume)
-{
- assert(handle);
- try {
- return (*handle)->setVolume(volume);
- }
- catch(AUD_Exception&) {}
- return false;
-}
-
-int AUD_Handle_setPitch(AUD_Handle *handle, float pitch)
-{
- assert(handle);
- try {
- return (*handle)->setPitch(pitch);
- }
- catch(AUD_Exception&) {}
- return false;
-}
-
-AUD_Device *AUD_openReadDevice(AUD_DeviceSpecs specs)
-{
- try {
- return new AUD_Device(new AUD_ReadDevice(specs));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek)
-{
- assert(device);
- assert(sound);
-
- try {
- AUD_Handle handle = (*device)->play(*sound);
- if (handle.get()) {
- handle->seek(seek);
- return new AUD_Handle(handle);
- }
- }
- catch(AUD_Exception&)
- {
- }
- return NULL;
-}
-
-int AUD_setDeviceVolume(AUD_Device *device, float volume)
-{
- assert(device);
-
- try {
- (*device)->setVolume(volume);
- return true;
- }
- catch(AUD_Exception&) {}
-
- return false;
-}
-
-int AUD_Device_read(AUD_Device *device, data_t *buffer, int length)
-{
- assert(device);
- assert(buffer);
-
- try {
- return boost::dynamic_pointer_cast<AUD_ReadDevice>(*device)->read(buffer, length);
- }
- catch(AUD_Exception&)
- {
- return false;
- }
-}
-
-void AUD_Device_free(AUD_Device *device)
-{
- try {
- if(device != &AUD_device)
- delete device;
- }
- catch(AUD_Exception&)
- {
- }
-}
-
-float *AUD_readSoundBuffer(const char *filename, float low, float high,
- float attack, float release, float threshold,
- int accumulate, int additive, int square,
- float sthreshold, double samplerate, int *length)
-{
- AUD_Buffer buffer;
- AUD_DeviceSpecs specs;
- specs.channels = AUD_CHANNELS_MONO;
- specs.rate = (AUD_SampleRate)samplerate;
- boost::shared_ptr<AUD_IFactory> sound;
-
- boost::shared_ptr<AUD_IFactory> file = boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
-
- int position = 0;
-
- try {
- boost::shared_ptr<AUD_IReader> reader = file->createReader();
-
- AUD_SampleRate rate = reader->getSpecs().rate;
-
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_ChannelMapperFactory(file, specs));
-
- if (high < rate)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(sound, high));
- if (low > 0)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(sound, low));
-
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f));
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_LinearResampleFactory(sound, specs));
-
- if (square)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(sound, sthreshold));
-
- if (accumulate)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_AccumulatorFactory(sound, additive));
- else if (additive)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_SumFactory(sound));
-
- reader = sound->createReader();
-
- if (!reader.get())
- return NULL;
-
- int len;
- bool eos;
- do
- {
- len = samplerate;
- buffer.resize((position + len) * sizeof(float), true);
- reader->read(len, eos, buffer.getBuffer() + position);
- position += len;
- } while(!eos);
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-
- float * result = (float *)malloc(position * sizeof(float));
- memcpy(result, buffer.getBuffer(), position * sizeof(float));
- *length = position;
- return result;
-}
-
-static void pauseSound(AUD_Handle *handle)
-{
- assert(handle);
- (*handle)->pause();
-}
-
-AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds)
-{
- boost::shared_ptr<AUD_IFactory> silence = boost::shared_ptr<AUD_IFactory>(new AUD_SilenceFactory);
- boost::shared_ptr<AUD_IFactory> limiter = boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(silence, 0, seconds));
-
- AUD_MutexLock lock(*AUD_device);
-
- try {
- AUD_Handle handle2 = AUD_device->play(limiter);
- if (handle2.get()) {
- handle2->setStopCallback((stopCallback)pauseSound, handle);
- return new AUD_Handle(handle2);
- }
- }
- catch(AUD_Exception&)
- {
- }
-
- return NULL;
-}
-
-AUD_Sound *AUD_Sequence_create(float fps, int muted)
-{
- // specs are changed at a later point!
- AUD_Specs specs;
- specs.channels = AUD_CHANNELS_STEREO;
- specs.rate = AUD_RATE_48000;
- AUD_Sound *sequencer = new AUD_Sound(boost::shared_ptr<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
- return sequencer;
-}
-
-void AUD_Sequence_free(AUD_Sound *sequencer)
-{
- delete sequencer;
-}
-
-void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->mute(muted);
-}
-
-void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setFPS(fps);
-}
-
-AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
- float begin, float end, float skip)
-{
- if (!sound)
- return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(AUD_Sound(), begin, end, skip));
- return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(*sound, begin, end, skip));
-}
-
-void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->remove(*entry);
- delete entry;
-}
-
-void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip)
-{
- (*entry)->move(begin, end, skip);
-}
-
-void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute)
-{
- (*entry)->mute(mute);
-}
-
-void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound)
-{
- if (sound)
- (*entry)->setSound(*sound);
- else
- (*entry)->setSound(AUD_Sound());
-}
-
-void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
-{
- AUD_AnimateableProperty *prop = (*entry)->getAnimProperty(type);
- if (animated) {
- if (frame >= 0)
- prop->write(data, frame, 1);
- }
- else {
- prop->write(data);
- }
-}
-
-void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
-{
- AUD_AnimateableProperty *prop = dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->getAnimProperty(type);
- if (animated) {
- if (frame >= 0) {
- prop->write(data, frame, 1);
- }
- }
- else {
- prop->write(data);
- }
-}
-
-void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDistanceModel(static_cast<AUD_DistanceModel>(value));
-}
-
-void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDopplerFactor(value);
-}
-
-void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setSpeedOfSound(value);
-}
-
-void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setAttenuation(value);
-}
-
-void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeAngleInner(value);
-}
-
-void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeAngleOuter(value);
-}
-
-void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeVolumeOuter(value);
-}
-
-void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setDistanceMaximum(value);
-}
-
-void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setDistanceReference(value);
-}
-
-void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setRelative(value);
-}
-
-void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setVolumeMaximum(value);
-}
-
-void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setVolumeMinimum(value);
-}
-
-void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
-}
-
-void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(specs);
-}
-
-void AUD_seekSynchronizer(AUD_Handle *handle, float time)
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->seekPlayback(time);
- }
- else
-#endif
- {
- assert(handle);
- (*handle)->seek(time);
- }
-}
-
-float AUD_getSynchronizerPosition(AUD_Handle *handle)
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- return device->getPlaybackPosition();
- }
- else
-#endif
- {
- assert(handle);
- return (*handle)->getPosition();
- }
-}
-
-void AUD_playSynchronizer()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->startPlayback();
- }
-#endif
-}
-
-void AUD_stopSynchronizer()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->stopPlayback();
- }
-#endif
-}
-
-#ifdef WITH_JACK
-void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data)
-{
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->setSyncCallback(function, data);
- }
-}
-#endif
-
-int AUD_isSynchronizerPlaying()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- return device->doesPlayback();
- }
-#endif
- return -1;
-}
-
-int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt)
-{
- AUD_DeviceSpecs specs;
- sample_t *buf;
- AUD_Buffer aBuffer;
-
- specs.rate = AUD_RATE_INVALID;
- specs.channels = AUD_CHANNELS_MONO;
- specs.format = AUD_FORMAT_INVALID;
-
- boost::shared_ptr<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
-
- specs.specs = reader->getSpecs();
- int len;
- float samplejump = specs.rate / samples_per_second;
- float min, max, power, overallmax;
- bool eos;
-
- overallmax = 0;
-
- for (int i = 0; i < length; i++) {
- len = floor(samplejump * (i+1)) - floor(samplejump * i);
-
- if (*interrupt) {
- return 0;
- }
- aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
- buf = aBuffer.getBuffer();
-
- reader->read(len, eos, buf);
-
- max = min = *buf;
- power = *buf * *buf;
- for (int j = 1; j < len; j++) {
- if (buf[j] < min)
- min = buf[j];
- if (buf[j] > max)
- max = buf[j];
- power += buf[j] * buf[j];
- }
-
- buffer[i * 3] = min;
- buffer[i * 3 + 1] = max;
- buffer[i * 3 + 2] = sqrt(power) / len;
-
- if (overallmax < max)
- overallmax = max;
- if (overallmax < -min)
- overallmax = -min;
-
- if (eos) {
- length = i;
- break;
- }
- }
-
- if (overallmax > 1.0f) {
- for (int i = 0; i < length * 3; i++) {
- buffer[i] /= overallmax;
- }
- }
-
- return length;
-}
-
-AUD_Sound *AUD_Sound_copy(AUD_Sound *sound)
-{
- return new boost::shared_ptr<AUD_IFactory>(*sound);
-}
-
-void AUD_Handle_free(AUD_Handle *handle)
-{
- delete handle;
-}
-
-const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
-{
- try {
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
-
- f->setSpecs(specs.specs);
- boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
- reader->seek(start);
- boost::shared_ptr<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
- AUD_FileWriter::writeReader(reader, writer, length, buffersize);
-
- return NULL;
- }
- catch(AUD_Exception& e)
- {
- return e.str;
- }
-}
-
-const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
-{
- try {
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
-
- f->setSpecs(specs.specs);
-
- std::vector<boost::shared_ptr<AUD_IWriter> > writers;
-
- int channels = specs.channels;
- specs.channels = AUD_CHANNELS_MONO;
-
- for (int i = 0; i < channels; i++) {
- std::stringstream stream;
- std::string fn = filename;
- size_t index = fn.find_last_of('.');
- size_t index_slash = fn.find_last_of('/');
- size_t index_backslash = fn.find_last_of('\\');
-
- if ((index == std::string::npos) ||
- ((index < index_slash) && (index_slash != std::string::npos)) ||
- ((index < index_backslash) && (index_backslash != std::string::npos)))
- {
- stream << filename << "_" << (i + 1);
- }
- else {
- stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
- }
- writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
- }
-
- boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
- reader->seek(start);
- AUD_FileWriter::writeReader(reader, writers, length, buffersize);
-
- return NULL;
- }
- catch(AUD_Exception& e)
- {
- return e.str;
- }
-}
-
-AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, float volume, float start)
-{
- try {
- AUD_ReadDevice *device = new AUD_ReadDevice(specs);
- device->setQuality(true);
- device->setVolume(volume);
-
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sequencer->get());
-
- f->setSpecs(specs.specs);
-
- AUD_Handle handle = device->play(f->createQualityReader());
- if (handle.get()) {
- handle->seek(start);
- }
-
- return new AUD_Device(device);
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Device *AUD_Device_getCurrent(void)
-{
- return &AUD_device;
-}
-
-int AUD_isJackSupported(void)
-{
-#ifdef WITH_JACK
- return AUD_jack_supported();
-#else
- return 0;
-#endif
-}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
deleted file mode 100644
index cc9059a8e09..00000000000
--- a/intern/audaspace/intern/AUD_C-API.h
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file AUD_C-API.h
- * \ingroup audaspace
- */
-
-#ifndef __AUD_C_API_H__
-#define __AUD_C_API_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "AUD_Space.h"
-
-/// Supported output devices.
-typedef enum
-{
- AUD_NULL_DEVICE = 0,
- AUD_SDL_DEVICE,
- AUD_OPENAL_DEVICE,
- AUD_JACK_DEVICE
-} AUD_DeviceType;
-
-/// Sound information structure.
-typedef struct
-{
- AUD_Specs specs;
- float length;
-} AUD_SoundInfo;
-
-#ifndef AUD_CAPI_IMPLEMENTATION
- typedef void AUD_Sound;
- typedef void AUD_Handle;
- typedef void AUD_Device;
- typedef void AUD_SEntry;
- typedef float (*AUD_volumeFunction)(void *, void *, float);
- typedef void (*AUD_syncFunction)(void *, int, float);
-#endif
-
-/**
- * Initializes audio routines (FFMPEG/JACK if it is enabled).
- */
-extern void AUD_initOnce(void);
-
-/**
- * Unitinitializes an audio routines.
- */
-extern void AUD_exitOnce(void);
-
-/**
- * Initializes an audio device.
- * \param device The device type that should be used.
- * \param specs The audio specification to be used.
- * \param buffersize The buffersize for the device.
- * \return Whether the device has been initialized.
- */
-extern AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name);
-
-/**
- * Unitinitializes an audio device.
- */
-extern void AUD_exit(AUD_Device* device);
-
-/**
- * Locks the playback device.
- */
-extern void AUD_Device_lock(AUD_Device* device);
-
-/**
- * Unlocks the device.
- */
-extern void AUD_Device_unlock(AUD_Device* device);
-
-extern AUD_Channels AUD_Device_getChannels(AUD_Device* device);
-
-extern AUD_SampleRate AUD_Device_getRate(AUD_Device* device);
-
-/**
- * Returns information about a sound.
- * \param sound The sound to get the info about.
- * \return The AUD_SoundInfo structure with filled in data.
- */
-extern AUD_SoundInfo AUD_getInfo(AUD_Sound *sound);
-
-/**
- * Loads a sound file.
- * \param filename The filename of the sound file.
- * \return A handle of the sound file.
- */
-extern AUD_Sound *AUD_Sound_file(const char *filename);
-
-/**
- * Loads a sound file.
- * \param buffer The buffer which contains the sound file.
- * \param size The size of the buffer.
- * \return A handle of the sound file.
- */
-extern AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size);
-
-/**
- * Buffers a sound.
- * \param sound The sound to buffer.
- * \return A handle of the sound buffer.
- */
-extern AUD_Sound *AUD_Sound_cache(AUD_Sound *sound);
-
-/**
- * Rechannels the sound to be mono.
- * \param sound The sound to rechannel.
- * \return The mono sound.
- */
-extern AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels);
-
-/**
- * Delays a sound.
- * \param sound The sound to dealy.
- * \param delay The delay in seconds.
- * \return A handle of the delayed sound.
- */
-extern AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay);
-
-/**
- * Limits a sound.
- * \param sound The sound to limit.
- * \param start The start time in seconds.
- * \param end The stop time in seconds.
- * \return A handle of the limited sound.
- */
-extern AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end);
-
-/**
- * Ping pongs a sound.
- * \param sound The sound to ping pong.
- * \return A handle of the ping pong sound.
- */
-extern AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound);
-
-/**
- * Loops a sound.
- * \param sound The sound to loop.
- * \return A handle of the looped sound.
- */
-extern AUD_Sound *AUD_Sound_loop(AUD_Sound *sound);
-
-/**
- * Sets a remaining loop count of a looping sound that currently plays.
- * \param handle The playback handle.
- * \param loops The count of remaining loops, -1 for infinity.
- * \return Whether the handle is valid.
- */
-extern int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops);
-
-/**
- * Rectifies a sound.
- * \param sound The sound to rectify.
- * \return A handle of the rectified sound.
- */
-extern AUD_Sound *AUD_rectifySound(AUD_Sound *sound);
-
-/**
- * Unloads a sound of any type.
- * \param sound The handle of the sound.
- */
-extern void AUD_Sound_free(AUD_Sound *sound);
-
-/**
- * Plays back a sound file.
- * \param sound The handle of the sound file.
- * \param keep When keep is true the sound source will not be deleted but set to
- * paused when its end has been reached.
- * \return A handle to the played back sound.
- */
-extern AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep);
-
-/**
- * Pauses a played back sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been playing or not.
- */
-extern int AUD_Handle_pause(AUD_Handle *handle);
-
-/**
- * Resumes a paused sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been paused or not.
- */
-extern int AUD_Handle_resume(AUD_Handle *handle);
-
-/**
- * Stops a playing or paused sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_stop(AUD_Handle *handle);
-
-extern void AUD_Device_stopAll(void* device);
-
-/**
- * Sets the end behaviour of a playing or paused sound.
- * \param handle The handle to the sound.
- * \param keep When keep is true the sound source will not be deleted but set to
- * paused when its end has been reached.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_setKeep(AUD_Handle *handle, int keep);
-
-/**
- * Seeks a playing or paused sound.
- * \param handle The handle to the sound.
- * \param seekTo From where the sound file should be played back in seconds.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo);
-
-/**
- * Retrieves the playback position of a handle.
- * \param handle The handle to the sound.
- * \return The current playback position in seconds or 0.0 if the handle is
- * invalid.
- */
-extern float AUD_Handle_getPosition(AUD_Handle *handle);
-
-/**
- * Returns the status of a playing, paused or stopped sound.
- * \param handle The handle to the sound.
- * \return The status of the sound behind the handle.
- */
-extern AUD_Status AUD_Handle_getStatus(AUD_Handle *handle);
-
-/**
- * Sets the listener location.
- * \param location The new location.
- */
-extern int AUD_Device_setListenerLocation(const float location[3]);
-
-/**
- * Sets the listener velocity.
- * \param velocity The new velocity.
- */
-extern int AUD_Device_setListenerVelocity(const float velocity[3]);
-
-/**
- * Sets the listener orientation.
- * \param orientation The new orientation as quaternion.
- */
-extern int AUD_Device_setListenerOrientation(const float orientation[4]);
-
-/**
- * Sets the speed of sound.
- * This value is needed for doppler effect calculation.
- * \param speed The new speed of sound.
- */
-extern int AUD_Device_setSpeedOfSound(void* device, float speed);
-
-/**
- * Sets the doppler factor.
- * This value is a scaling factor for the velocity vectors of sources and
- * listener which is used while calculating the doppler effect.
- * \param factor The new doppler factor.
- */
-extern int AUD_Device_setDopplerFactor(void* device, float factor);
-
-/**
- * Sets the distance model.
- * \param model distance model.
- */
-extern int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model);
-
-/**
- * Sets the location of a source.
- * \param handle The handle of the source.
- * \param location The new location.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3]);
-
-/**
- * Sets the velocity of a source.
- * \param handle The handle of the source.
- * \param velocity The new velocity.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3]);
-
-/**
- * Sets the orientation of a source.
- * \param handle The handle of the source.
- * \param orientation The new orientation as quaternion.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4]);
-
-/**
- * Sets whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \param relative Whether the source is relative.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setRelative(AUD_Handle *handle, int relative);
-
-/**
- * Sets the maximum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new maximum volume.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume);
-
-/**
- * Sets the minimum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new minimum volume.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume);
-
-/**
- * Sets the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \param distance The new maximum distance.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance);
-
-/**
- * Sets the reference distance of a source.
- * \param handle The handle of the source.
- * \param distance The new reference distance.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance);
-
-/**
- * Sets the attenuation of a source.
- * This value is used for distance calculation.
- * \param handle The handle of the source.
- * \param factor The new attenuation.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor);
-
-/**
- * Sets the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new outer angle of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle);
-
-/**
- * Sets the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new inner angle of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle);
-
-/**
- * Sets the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \param volume The new outer volume of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume);
-
-/**
- * Sets the volume of a played back sound.
- * \param handle The handle to the sound.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolume(AUD_Handle *handle, float volume);
-
-/**
- * Sets the pitch of a played back sound.
- * \param handle The handle to the sound.
- * \param pitch The new pitch.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setPitch(AUD_Handle *handle, float pitch);
-
-/**
- * Opens a read device, with which audio data can be read.
- * \param specs The specification of the audio data.
- * \return A device handle.
- */
-extern AUD_Device *AUD_openReadDevice(AUD_DeviceSpecs specs);
-
-/**
- * Sets the main volume of a device.
- * \param device The device.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_setDeviceVolume(AUD_Device *device, float volume);
-
-/**
- * Plays back a sound file through a read device.
- * \param device The read device.
- * \param sound The handle of the sound file.
- * \param seek The position where the sound should be seeked to.
- * \return A handle to the played back sound.
- */
-extern AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek);
-
-/**
- * Reads the next samples into the supplied buffer.
- * \param device The read device.
- * \param buffer The target buffer.
- * \param length The length in samples to be filled.
- * \return True if the reading succeeded, false if there are no sounds
- * played back currently, in that case the buffer is filled with
- * silence.
- */
-extern int AUD_Device_read(AUD_Device *device, data_t *buffer, int length);
-
-/**
- * Closes a read device.
- * \param device The read device.
- */
-extern void AUD_Device_free(AUD_Device *device);
-
-/**
- * Reads a sound file into a newly created float buffer.
- * The sound is therefore bandpassed, rectified and resampled.
- */
-extern float *AUD_readSoundBuffer(const char *filename, float low, float high,
- float attack, float release, float threshold,
- int accumulate, int additive, int square,
- float sthreshold, double samplerate,
- int *length);
-
-/**
- * Pauses a playing sound after a specific amount of time.
- * \param handle The handle to the sound.
- * \param seconds The time in seconds.
- * \return The silence handle.
- */
-extern AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds);
-
-/**
- * Creates a new sequenced sound scene.
- * \param fps The FPS of the scene.
- * \param muted Whether the scene is muted.
- * \return The new sound scene.
- */
-extern AUD_Sound *AUD_Sequence_create(float fps, int muted);
-
-/**
- * Deletes a sound scene.
- * \param sequencer The sound scene.
- */
-extern void AUD_Sequence_free(AUD_Sound *sequencer);
-
-/**
- * Sets the muting state of the scene.
- * \param sequencer The sound scene.
- * \param muted Whether the scene is muted.
- */
-extern void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted);
-
-/**
- * Sets the scene's FPS.
- * \param sequencer The sound scene.
- * \param fps The new FPS.
- */
-extern void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps);
-
-/**
- * Adds a new entry to the scene.
- * \param sequencer The sound scene.
- * \param sound The sound this entry should play.
- * \param begin The start time.
- * \param end The end time or a negative value if determined by the sound.
- * \param skip How much seconds should be skipped at the beginning.
- * \return The entry added.
- */
-extern AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
- float begin, float end, float skip);
-
-/**
- * Removes an entry from the scene.
- * \param sequencer The sound scene.
- * \param entry The entry to remove.
- */
-extern void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry);
-
-/**
- * Moves the entry.
- * \param entry The sequenced entry.
- * \param begin The new start time.
- * \param end The new end time or a negative value if unknown.
- * \param skip How many seconds to skip at the beginning.
- */
-extern void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip);
-
-/**
- * Sets the muting state of the entry.
- * \param entry The sequenced entry.
- * \param mute Whether the entry should be muted or not.
- */
-extern void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute);
-
-/**
- * Sets the sound of the entry.
- * \param entry The sequenced entry.
- * \param sound The new sound.
- */
-extern void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound);
-
-/**
- * Writes animation data to a sequenced entry.
- * \param entry The sequenced entry.
- * \param type The type of animation data.
- * \param frame The frame this data is for.
- * \param data The data to write.
- * \param animated Whether the attribute is animated.
- */
-extern void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
-
-/**
- * Writes animation data to a sequenced entry.
- * \param sequencer The sound scene.
- * \param type The type of animation data.
- * \param frame The frame this data is for.
- * \param data The data to write.
- * \param animated Whether the attribute is animated.
- */
-extern void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
-
-/**
- * Sets the distance model of a sequence.
- * param sequence The sequence to set the distance model from.
- * param value The new distance model to set.
- */
-extern void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value);
-
-/**
- * Sets the doppler factor of a sequence.
- * param sequence The sequence to set the doppler factor from.
- * param value The new doppler factor to set.
- */
-extern void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value);
-
-/**
- * Sets the speed of sound of a sequence.
- * param sequence The sequence to set the speed of sound from.
- * param value The new speed of sound to set.
- */
-extern void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value);
-/**
- * Sets the attenuation of a sequence_entry.
- * param sequence_entry The sequence_entry to set the attenuation from.
- * param value The new attenuation to set.
- */
-extern void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone angle inner of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone angle inner from.
- * param value The new cone angle inner to set.
- */
-extern void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone angle outer of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone angle outer from.
- * param value The new cone angle outer to set.
- */
-extern void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone volume outer of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone volume outer from.
- * param value The new cone volume outer to set.
- */
-extern void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the distance maximum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the distance maximum from.
- * param value The new distance maximum to set.
- */
-extern void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the distance reference of a sequence_entry.
- * param sequence_entry The sequence_entry to set the distance reference from.
- * param value The new distance reference to set.
- */
-extern void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the relative of a sequence_entry.
- * param sequence_entry The sequence_entry to set the relative from.
- * param value The new relative to set.
- */
-extern void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value);
-
-/**
- * Sets the volume maximum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the volume maximum from.
- * param value The new volume maximum to set.
- */
-extern void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the volume minimum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the volume minimum from.
- * param value The new volume minimum to set.
- */
-extern void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the audio output specification of the sound scene to the specs of the
- * current playback device.
- * \param sequencer The sound scene.
- */
-extern void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer);
-
-/**
- * Sets the audio output specification of the sound scene.
- * \param sequencer The sound scene.
- * \param specs The new specification.
- */
-extern void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs);
-
-/**
- * Seeks sequenced sound scene playback.
- * \param handle Playback handle.
- * \param time Time in seconds to seek to.
- */
-extern void AUD_seekSynchronizer(AUD_Handle *handle, float time);
-
-/**
- * Returns the current sound scene playback time.
- * \param handle Playback handle.
- * \return The playback time in seconds.
- */
-extern float AUD_getSynchronizerPosition(AUD_Handle *handle);
-
-/**
- * Starts the playback of jack transport if possible.
- */
-extern void AUD_playSynchronizer(void);
-
-/**
- * Stops the playback of jack transport if possible.
- */
-extern void AUD_stopSynchronizer(void);
-
-#ifdef WITH_JACK
-/**
- * Sets the sync callback for jack transport.
- * \param function The callback function.
- * \param data The data parameter for the callback.
- */
-extern void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data);
-#endif
-
-/**
- * Returns whether jack transport is currently playing.
- * \return Whether jack transport is currently playing.
- */
-extern int AUD_isSynchronizerPlaying(void);
-
-/**
- * Reads a sound into a buffer for drawing at a specific sampling rate.
- * \param sound The sound to read.
- * \param buffer The buffer to write to. Must have a size of 3*4*length.
- * \param length How many samples to read from the sound.
- * \param samples_per_second How many samples to read per second of the sound.
- * \return How many samples really have been read. Always <= length.
- */
-extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt);
-
-/**
- * Copies a sound.
- * \param sound Sound to copy.
- * \return Copied sound.
- */
-extern AUD_Sound *AUD_Sound_copy(AUD_Sound *sound);
-
-/**
- * Frees a handle.
- * \param channel Handle to free.
- */
-extern void AUD_Handle_free(AUD_Handle *channel);
-
-/**
- * Creates a new set.
- * \return The new set.
- */
-extern void *AUD_createSet(void);
-
-/**
- * Deletes a set.
- * \param set The set to delete.
- */
-extern void AUD_destroySet(void *set);
-
-/**
- * Removes an entry from a set.
- * \param set The set work on.
- * \param entry The entry to remove.
- * \return Whether the entry was in the set or not.
- */
-extern char AUD_removeSet(void *set, void *entry);
-
-/**
- * Adds a new entry to a set.
- * \param set The set work on.
- * \param entry The entry to add.
- */
-extern void AUD_addSet(void *set, void *entry);
-
-/**
- * Removes one entry from a set and returns it.
- * \param set The set work on.
- * \return The entry or NULL if the set is empty.
- */
-extern void *AUD_getSet(void *set);
-
-/**
- * Mixes a sound down into a file.
- * \param sound The sound scene to mix down.
- * \param start The start frame.
- * \param length The count of frames to write.
- * \param buffersize How many samples should be written at once.
- * \param filename The file to write to.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return An error message or NULL in case of success.
- */
-extern const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length,
- unsigned int buffersize, const char *filename,
- AUD_DeviceSpecs specs, AUD_Container format,
- AUD_Codec codec, unsigned int bitrate);
-
-/**
- * Mixes a sound down into multiple files.
- * \param sound The sound scene to mix down.
- * \param start The start frame.
- * \param length The count of frames to write.
- * \param buffersize How many samples should be written at once.
- * \param filename The file to write to, the channel number and an underscore are added at the beginning.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return An error message or NULL in case of success.
- */
-extern const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsigned int length,
- unsigned int buffersize, const char *filename,
- AUD_DeviceSpecs specs, AUD_Container format,
- AUD_Codec codec, unsigned int bitrate);
-
-/**
- * Opens a read device and prepares it for mixdown of the sound scene.
- * \param specs Output audio specifications.
- * \param sequencer The sound scene to mix down.
- * \param volume The overall mixdown volume.
- * \param start The start time of the mixdown in the sound scene.
- * \return The read device for the mixdown.
- */
-extern AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, float volume, float start);
-
-#ifdef WITH_PYTHON
-/**
- * Retrieves the python factory of a sound.
- * \param sound The sound factory.
- * \return The python factory.
- */
-extern void *AUD_getPythonSound(AUD_Sound *sound);
-
-/**
- * Retrieves the sound factory of a python factory.
- * \param sound The python factory.
- * \return The sound factory.
- */
-extern AUD_Sound *AUD_getSoundFromPython(void *sound);
-#endif
-
-extern AUD_Device *AUD_Device_getCurrent(void);
-
-extern int AUD_isJackSupported(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__AUD_C_API_H__
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
deleted file mode 100644
index f4ba5d05ff0..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ChannelMapperFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ChannelMapperFactory.h"
-#include "AUD_ChannelMapperReader.h"
-
-#include <cstring>
-
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ChannelMapperFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
- return boost::shared_ptr<AUD_IReader>(new AUD_ChannelMapperReader(reader, m_specs.channels));
-}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
deleted file mode 100644
index 611b5041c39..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ChannelMapperFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CHANNELMAPPERFACTORY_H__
-#define __AUD_CHANNELMAPPERFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a reader that maps a sound source's channels to a
- * specific output channel count.
- */
-class AUD_ChannelMapperFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ChannelMapperFactory(const AUD_ChannelMapperFactory&);
- AUD_ChannelMapperFactory& operator=(const AUD_ChannelMapperFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_CHANNELMAPPERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
deleted file mode 100644
index 8b983d5c43d..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ChannelMapperReader.cpp
- * \ingroup audaspaceintern
- */
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
-#endif
-
-#include "AUD_ChannelMapperReader.h"
-
-AUD_ChannelMapperReader::AUD_ChannelMapperReader(boost::shared_ptr<AUD_IReader> reader,
- AUD_Channels channels) :
- AUD_EffectReader(reader), m_target_channels(channels),
- m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0), m_map_size(0), m_mono_angle(0)
-{
-}
-
-AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
-{
- delete[] m_mapping;
-}
-
-void AUD_ChannelMapperReader::setChannels(AUD_Channels channels)
-{
- m_target_channels = channels;
- calculateMapping();
-}
-
-void AUD_ChannelMapperReader::setMonoAngle(float angle)
-{
- if(angle != angle)
- angle = 0;
- m_mono_angle = angle;
- if(m_source_channels == AUD_CHANNELS_MONO)
- calculateMapping();
-}
-
-float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
-{
- alpha = beta - alpha;
-
- if(alpha > M_PI)
- alpha -= 2 * M_PI;
- if(alpha < -M_PI)
- alpha += 2 * M_PI;
-
- return alpha;
-}
-
-void AUD_ChannelMapperReader::calculateMapping()
-{
- if(m_map_size < m_source_channels * m_target_channels)
- {
- delete[] m_mapping;
- m_mapping = new float[m_source_channels * m_target_channels];
- m_map_size = m_source_channels * m_target_channels;
- }
-
- for(int i = 0; i < m_source_channels * m_target_channels; i++)
- m_mapping[i] = 0;
-
- const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
- const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
-
- int lfe = -1;
-
- for(int i = 0; i < m_target_channels; i++)
- {
- if(target_channels[i] == AUD_CHANNEL_LFE)
- {
- lfe = i;
- break;
- }
- }
-
- const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
- const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
-
- if(m_source_channels == AUD_CHANNELS_MONO)
- source_angles = &m_mono_angle;
-
- int channel_left, channel_right;
- float angle_left, angle_right, angle;
-
- for(int i = 0; i < m_source_channels; i++)
- {
- if(source_channels[i] == AUD_CHANNEL_LFE)
- {
- if(lfe != -1)
- m_mapping[lfe * m_source_channels + i] = 1;
-
- continue;
- }
-
- channel_left = channel_right = -1;
- angle_left = -2 * M_PI;
- angle_right = 2 * M_PI;
-
- for(int j = 0; j < m_target_channels; j++)
- {
- if(j == lfe)
- continue;
- angle = angleDistance(source_angles[i], target_angles[j]);
- if(angle < 0)
- {
- if(angle > angle_left)
- {
- angle_left = angle;
- channel_left = j;
- }
- }
- else
- {
- if(angle < angle_right)
- {
- angle_right = angle;
- channel_right = j;
- }
- }
- }
-
- angle = angle_right - angle_left;
- if(channel_right == -1 || angle == 0)
- {
- m_mapping[channel_left * m_source_channels + i] = 1;
- }
- else if(channel_left == -1)
- {
- m_mapping[channel_right * m_source_channels + i] = 1;
- }
- else
- {
- m_mapping[channel_left * m_source_channels + i] = cos(M_PI_2 * angle_left / angle);
- m_mapping[channel_right * m_source_channels + i] = cos(M_PI_2 * angle_right / angle);
- }
- }
-
- /* AUD_XXX for(int i = 0; i < m_source_channels; i++)
- {
- for(int j = 0; j < m_target_channels; j++)
- {
- std::cout << m_mapping[i * m_source_channels + j] << " ";
- }
- std::cout << std::endl;
- }*/
-}
-
-AUD_Specs AUD_ChannelMapperReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.channels = m_target_channels;
- return specs;
-}
-
-void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Channels channels = m_reader->getSpecs().channels;
- if(channels != m_source_channels)
- {
- m_source_channels = channels;
- calculateMapping();
- }
-
- if(m_source_channels == m_target_channels)
- {
- m_reader->read(length, eos, buffer);
- return;
- }
-
- m_buffer.assureSize(length * channels * sizeof(sample_t));
-
- sample_t* in = m_buffer.getBuffer();
-
- m_reader->read(length, eos, in);
-
- sample_t sum;
-
- for(int i = 0; i < length; i++)
- {
- for(int j = 0; j < m_target_channels; j++)
- {
- sum = 0;
- for(int k = 0; k < m_source_channels; k++)
- sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
- buffer[i * m_target_channels + j] = sum;
- }
- }
-}
-
-const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] =
-{
- AUD_CHANNEL_FRONT_CENTER
-};
-
-const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_LFE
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_CENTER,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT,
- AUD_CHANNEL_SIDE_LEFT,
- AUD_CHANNEL_SIDE_RIGHT
-};
-
-const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] =
-{
- AUD_ChannelMapperReader::MONO_MAP,
- AUD_ChannelMapperReader::STEREO_MAP,
- AUD_ChannelMapperReader::STEREO_LFE_MAP,
- AUD_ChannelMapperReader::SURROUND4_MAP,
- AUD_ChannelMapperReader::SURROUND5_MAP,
- AUD_ChannelMapperReader::SURROUND51_MAP,
- AUD_ChannelMapperReader::SURROUND61_MAP,
- AUD_ChannelMapperReader::SURROUND71_MAP
-};
-
-const float AUD_ChannelMapperReader::MONO_ANGLES[] =
-{
- 0.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::STEREO_ANGLES[] =
-{
- -90.0f * M_PI / 180.0f,
- 90.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] =
-{
- -90.0f * M_PI / 180.0f,
- 90.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] =
-{
- -45.0f * M_PI / 180.0f,
- 45.0f * M_PI / 180.0f,
- -135.0f * M_PI / 180.0f,
- 135.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 180.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f,
- -150.0f * M_PI / 180.0f,
- 150.0f * M_PI / 180.0f
-};
-
-const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] =
-{
- AUD_ChannelMapperReader::MONO_ANGLES,
- AUD_ChannelMapperReader::STEREO_ANGLES,
- AUD_ChannelMapperReader::STEREO_LFE_ANGLES,
- AUD_ChannelMapperReader::SURROUND4_ANGLES,
- AUD_ChannelMapperReader::SURROUND5_ANGLES,
- AUD_ChannelMapperReader::SURROUND51_ANGLES,
- AUD_ChannelMapperReader::SURROUND61_ANGLES,
- AUD_ChannelMapperReader::SURROUND71_ANGLES
-};
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
deleted file mode 100644
index b122b070d29..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ChannelMapperReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CHANNELMAPPERREADER_H__
-#define __AUD_CHANNELMAPPERREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class maps a sound source's channels to a specific output channel count.
- * \note The input sample format must be float.
- */
-class AUD_ChannelMapperReader : public AUD_EffectReader
-{
-private:
- /**
- * The sound reading buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The output specification.
- */
- AUD_Channels m_target_channels;
-
- /**
- * The channel count of the reader.
- */
- AUD_Channels m_source_channels;
-
- /**
- * The mapping specification.
- */
- float* m_mapping;
-
- /**
- * The size of the mapping.
- */
- int m_map_size;
-
- /**
- * The mono source angle.
- */
- float m_mono_angle;
-
- static const AUD_Channel MONO_MAP[];
- static const AUD_Channel STEREO_MAP[];
- static const AUD_Channel STEREO_LFE_MAP[];
- static const AUD_Channel SURROUND4_MAP[];
- static const AUD_Channel SURROUND5_MAP[];
- static const AUD_Channel SURROUND51_MAP[];
- static const AUD_Channel SURROUND61_MAP[];
- static const AUD_Channel SURROUND71_MAP[];
- static const AUD_Channel* CHANNEL_MAPS[];
-
- static const float MONO_ANGLES[];
- static const float STEREO_ANGLES[];
- static const float STEREO_LFE_ANGLES[];
- static const float SURROUND4_ANGLES[];
- static const float SURROUND5_ANGLES[];
- static const float SURROUND51_ANGLES[];
- static const float SURROUND61_ANGLES[];
- static const float SURROUND71_ANGLES[];
- static const float* CHANNEL_ANGLES[];
-
- // hide copy constructor and operator=
- AUD_ChannelMapperReader(const AUD_ChannelMapperReader&);
- AUD_ChannelMapperReader& operator=(const AUD_ChannelMapperReader&);
-
- /**
- * Calculates the mapping matrix.
- */
- void calculateMapping();
-
- /**
- * Calculates the distance between two angles.
- */
- float angleDistance(float alpha, float beta);
-
-public:
- /**
- * Creates a channel mapper reader.
- * \param reader The reader to map.
- * \param mapping The mapping specification as two dimensional float array.
- */
- AUD_ChannelMapperReader(boost::shared_ptr<AUD_IReader> reader, AUD_Channels channels);
-
- /**
- * Destroys the reader.
- */
- ~AUD_ChannelMapperReader();
-
- /**
- * Sets the requested channel output count.
- * \param channels The channel output count.
- */
- void setChannels(AUD_Channels channels);
-
- /**
- * Sets the angle for mono sources.
- * \param angle The angle for mono sources.
- */
- void setMonoAngle(float angle);
-
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_CHANNELMAPPERREADER_H__
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
deleted file mode 100644
index 7cbf64f1697..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterFactory.h"
-#include "AUD_ConverterReader.h"
-
-AUD_ConverterFactory::AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ConverterFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
-
- return reader;
-}
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
deleted file mode 100644
index 2c9c82d235b..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERFACTORY_H__
-#define __AUD_CONVERTERFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a converter reader that is able to convert from one
- * audio format to another.
- */
-class AUD_ConverterFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ConverterFactory(const AUD_ConverterFactory&);
- AUD_ConverterFactory& operator=(const AUD_ConverterFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_CONVERTERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
deleted file mode 100644
index c20f19a7e67..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterFunctions.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-
-#define AUD_U8_0 0x80
-#define AUD_S16_MAX ((int16_t)0x7FFF)
-#define AUD_S16_MIN ((int16_t)0x8000)
-#define AUD_S16_FLT 32767.0f
-#define AUD_S32_MAX ((int32_t)0x7FFFFFFF)
-#define AUD_S32_MIN ((int32_t)0x80000000)
-#define AUD_S32_FLT 2147483647.0f
-#define AUD_FLT_MAX 1.0f
-#define AUD_FLT_MIN -1.0f
-
-void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
-}
-
-void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
-{
- for(int i = length - 1; i >= 0; i--)
- {
- target[i*3] = source[i] - AUD_U8_0;
- target[i*3+1] = 0;
- target[i*3+2] = 0;
- }
-}
-
-void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
-{
- for(int i = length - 1; i >= 0; i--)
- {
- target[i*3+2] = source[i] - AUD_U8_0;
- target[i*3+1] = 0;
- target[i*3] = 0;
- }
-}
-
-void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
-}
-
-void AUD_convert_u8_float(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
-}
-
-void AUD_convert_u8_double(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
-}
-
-void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
- target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
-}
-
-void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int16_t t;
- for(int i = length - 1; i >= 0; i--)
- {
- t = s[i];
- target[i*3] = t >> 8 & 0xFF;
- target[i*3+1] = t & 0xFF;
- target[i*3+2] = 0;
- }
-}
-
-void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int16_t t;
- for(int i = length - 1; i >= 0; i--)
- {
- t = s[i];
- target[i*3+2] = t >> 8 & 0xFF;
- target[i*3+1] = t & 0xFF;
- target[i*3] = 0;
- }
-}
-
-void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = ((int32_t)s[i]) << 16;
-}
-
-void AUD_convert_s16_float(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- float* t = (float*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S16_FLT;
-}
-
-void AUD_convert_s16_double(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S16_FLT;
-}
-
-void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
-{
- for(int i = 0; i < length; i++)
- target[i] = source[i*3] ^ AUD_U8_0;
-}
-
-void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
-{
- for(int i = 0; i < length; i++)
- target[i] = source[i*3+2] ^ AUD_U8_0;
-}
-
-void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = 0; i < length; i++)
- t[i] = source[i*3] << 8 | source[i*3+1];
-}
-
-void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = 0; i < length; i++)
- t[i] = source[i*3+2] << 8 | source[i*3+1];
-}
-
-void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
-{
- memcpy(target, source, length * 3);
-}
-
-void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
-}
-
-void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
-}
-
-void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
- target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
-}
-
-void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- int32_t* s = (int32_t*) source;
- for(int i = 0; i < length; i++)
- t[i] = s[i] >> 16;
-}
-
-void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- int32_t t;
- for(int i = 0; i < length; i++)
- {
- t = s[i];
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- int32_t t;
- for(int i = 0; i < length; i++)
- {
- t = s[i];
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_s32_float(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- float* t = (float*) target;
- for(int i = 0; i < length; i++)
- t[i] = s[i] / AUD_S32_FLT;
-}
-
-void AUD_convert_s32_double(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S32_FLT;
-}
-
-void AUD_convert_float_u8(data_t* target, data_t* source, int length)
-{
- float* s = (float*) source;
- float t;
- for(int i = 0; i < length; i++)
- {
- t = s[i] + AUD_FLT_MAX;
- if(t <= 0.0f)
- target[i] = 0;
- else if(t >= 2.0f)
- target[i] = 255;
- else
- target[i] = (unsigned char)(t*127);
- }
-}
-
-void AUD_convert_float_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S16_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S16_MAX;
- else
- t[i] = (int16_t)(s[i] * AUD_S16_MAX);
- }
-}
-
-void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t t;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t t;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_float_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S32_MAX;
- else
- t[i] = (int32_t)(s[i]*AUD_S32_MAX);
- }
-}
-
-void AUD_convert_float_double(data_t* target, data_t* source, int length)
-{
- float* s = (float*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i];
-}
-
-void AUD_convert_double_u8(data_t* target, data_t* source, int length)
-{
- double* s = (double*) source;
- double t;
- for(int i = 0; i < length; i++)
- {
- t = s[i] + AUD_FLT_MAX;
- if(t <= 0.0)
- target[i] = 0;
- else if(t >= 2.0)
- target[i] = 255;
- else
- target[i] = (unsigned char)(t*127);
- }
-}
-
-void AUD_convert_double_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S16_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S16_MAX;
- else
- t[i] = (int16_t)(s[i]*AUD_S16_MAX);
- }
-}
-
-void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t t;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t t;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_double_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S32_MAX;
- else
- t[i] = (int32_t)(s[i]*AUD_S32_MAX);
- }
-}
-
-void AUD_convert_double_float(data_t* target, data_t* source, int length)
-{
- double* s = (double*) source;
- float* t = (float*) target;
- for(int i = 0; i < length; i++)
- t[i] = s[i];
-}
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
deleted file mode 100644
index eca2b327b8c..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFunctions.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterFunctions.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERFUNCTIONS_H__
-#define __AUD_CONVERTERFUNCTIONS_H__
-
-#include "AUD_Space.h"
-
-#include <cstring>
-#include <stdint.h>
-
-typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
-
-template <class T>
-void AUD_convert_copy(data_t* target, data_t* source, int length)
-{
- memcpy(target, source, length*sizeof(T));
-}
-
-void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_float(data_t* target, data_t* source, int length);
-
-#endif //__AUD_CONVERTERFUNCTIONS_H__
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
deleted file mode 100644
index a90a54670e8..00000000000
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterReader.h"
-
-AUD_ConverterReader::AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader,
- AUD_DeviceSpecs specs) :
- AUD_EffectReader(reader),
- m_format(specs.format)
-{
- switch(m_format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
-#ifdef __BIG_ENDIAN__
- m_convert = AUD_convert_float_s24_be;
-#else
- m_convert = AUD_convert_float_s24_le;
-#endif
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
-}
-
-void AUD_ConverterReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_buffer.assureSize(length * samplesize);
-
- m_reader->read(length, eos, m_buffer.getBuffer());
-
- m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(),
- length * specs.channels);
-}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
deleted file mode 100644
index 987b7c70279..00000000000
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ConverterReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERREADER_H__
-#define __AUD_CONVERTERREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class converts a sound source from one to another format.
- */
-class AUD_ConverterReader : public AUD_EffectReader
-{
-private:
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The target specification.
- */
- AUD_SampleFormat m_format;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- // hide copy constructor and operator=
- AUD_ConverterReader(const AUD_ConverterReader&);
- AUD_ConverterReader& operator=(const AUD_ConverterReader&);
-
-public:
- /**
- * Creates a converter reader.
- * \param reader The reader to convert.
- * \param specs The target specification.
- */
- AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader, AUD_DeviceSpecs specs);
-
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_CONVERTERREADER_H__
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
deleted file mode 100644
index f9353db6677..00000000000
--- a/intern/audaspace/intern/AUD_FileFactory.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_FileFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#ifdef WITH_FFMPEG
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#include "AUD_FFMPEGReader.h"
-#endif
-
-#include "AUD_FileFactory.h"
-
-#include <cstring>
-
-#ifdef WITH_SNDFILE
-#include "AUD_SndFileReader.h"
-#endif
-
-AUD_FileFactory::AUD_FileFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-static const char* read_error = "AUD_FileFactory: File couldn't be read.";
-
-boost::shared_ptr<AUD_IReader> AUD_FileFactory::createReader()
-{
-#ifdef WITH_SNDFILE
- try
- {
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_filename));
- }
- catch(AUD_Exception&) {}
-#endif
-
-#ifdef WITH_FFMPEG
- try
- {
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_filename));
- }
- catch(AUD_Exception&) {}
-#endif
-
- AUD_THROW(AUD_ERROR_FILE, read_error);
-}
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
deleted file mode 100644
index 35c8db731b4..00000000000
--- a/intern/audaspace/intern/AUD_FileFactory.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_FileFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_FILEFACTORY_H__
-#define __AUD_FILEFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory tries to read a sound file via all available file readers.
- */
-class AUD_FileFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_FileFactory(const AUD_FileFactory&);
- AUD_FileFactory& operator=(const AUD_FileFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_FileFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_FileFactory(const data_t* buffer, int size);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_FILEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_FileWriter.cpp b/intern/audaspace/intern/AUD_FileWriter.cpp
deleted file mode 100644
index e3072fa82e0..00000000000
--- a/intern/audaspace/intern/AUD_FileWriter.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_FileWriter.cpp
- * \ingroup audaspaceintern
- */
-
-#ifdef WITH_FFMPEG
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#include "AUD_FFMPEGWriter.h"
-#endif
-
-#ifdef WITH_SNDFILE
-#include "AUD_SndFileWriter.h"
-#endif
-
-#include "AUD_FileWriter.h"
-#include "AUD_Buffer.h"
-
-static const char* write_error = "AUD_FileWriter: File couldn't be written.";
-
-boost::shared_ptr<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD_DeviceSpecs specs,
- AUD_Container format, AUD_Codec codec, unsigned int bitrate)
-{
-#ifdef WITH_SNDFILE
- try
- {
- return boost::shared_ptr<AUD_IWriter>(new AUD_SndFileWriter(filename, specs, format, codec, bitrate));
- }
- catch(AUD_Exception&) {}
-#endif
-
-#ifdef WITH_FFMPEG
- try
- {
- return boost::shared_ptr<AUD_IWriter>(new AUD_FFMPEGWriter(filename, specs, format, codec, bitrate));
- }
- catch(AUD_Exception&) {}
-#endif
-
- AUD_THROW(AUD_ERROR_SPECS, write_error);
-}
-
-void AUD_FileWriter::writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize)
-{
- AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
- sample_t* buf = buffer.getBuffer();
-
- int len;
- bool eos = false;
- int channels = writer->getSpecs().channels;
-
- for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
- {
- len = buffersize;
- if((len > length - pos) && (length > 0))
- len = length - pos;
- reader->read(len, eos, buf);
-
- for(int i = 0; i < len * channels; i++)
- {
- // clamping!
- if(buf[i] > 1)
- buf[i] = 1;
- else if(buf[i] < -1)
- buf[i] = -1;
- }
-
- writer->write(len, buf);
- }
-}
-
-void AUD_FileWriter::writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
-{
- AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
- AUD_Buffer buffer2(buffersize * sizeof(sample_t));
- sample_t* buf = buffer.getBuffer();
- sample_t* buf2 = buffer2.getBuffer();
-
- int len;
- bool eos = false;
- int channels = reader->getSpecs().channels;
-
- for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
- {
- len = buffersize;
- if((len > length - pos) && (length > 0))
- len = length - pos;
- reader->read(len, eos, buf);
-
- for(int channel = 0; channel < channels; channel++)
- {
- for(int i = 0; i < len; i++)
- {
- // clamping!
- if(buf[i * channels + channel] > 1)
- buf2[i] = 1;
- else if(buf[i * channels + channel] < -1)
- buf2[i] = -1;
- else
- buf2[i] = buf[i * channels + channel];
- }
-
- writers[channel]->write(len, buf2);
- }
- }
-}
diff --git a/intern/audaspace/intern/AUD_FileWriter.h b/intern/audaspace/intern/AUD_FileWriter.h
deleted file mode 100644
index 3291c1ad03a..00000000000
--- a/intern/audaspace/intern/AUD_FileWriter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_FileWriter.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_FILEWRITER_H__
-#define __AUD_FILEWRITER_H__
-
-#include <string>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-
-#include "AUD_IWriter.h"
-#include "AUD_IReader.h"
-
-/**
- * This class is able to create IWriter classes as well as write reads to them.
- */
-class AUD_FileWriter
-{
-private:
- // hide default constructor, copy constructor and operator=
- AUD_FileWriter();
- AUD_FileWriter(const AUD_FileWriter&);
- AUD_FileWriter& operator=(const AUD_FileWriter&);
-
-public:
- /**
- * Creates a new IWriter.
- * \param filename The file to write to.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return The writer to write data to.
- */
- static boost::shared_ptr<AUD_IWriter> createWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
-
- /**
- * Writes a reader to a writer.
- * \param reader The reader to read from.
- * \param writer The writer to write to.
- * \param length How many samples should be transferred.
- * \param buffersize How many samples should be transferred at once.
- */
- static void writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
-
- /**
- * Writes a reader to several writers.
- * \param reader The reader to read from.
- * \param writers The writers to write to.
- * \param length How many samples should be transferred.
- * \param buffersize How many samples should be transferred at once.
- */
- static void writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
-};
-
-#endif //__AUD_FILEWRITER_H__
diff --git a/intern/audaspace/intern/AUD_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h
deleted file mode 100644
index 1df710b7e5b..00000000000
--- a/intern/audaspace/intern/AUD_I3DDevice.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_I3DDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_I3DDEVICE_H__
-#define __AUD_I3DDEVICE_H__
-
-#include "AUD_Space.h"
-#include "AUD_3DMath.h"
-
-/**
- * This class represents an output device for 3D sound.
- */
-class AUD_I3DDevice
-{
-public:
- /**
- * Retrieves the listener location.
- * \return The listener location.
- */
- virtual AUD_Vector3 getListenerLocation() const=0;
-
- /**
- * Sets the listener location.
- * \param location The new location.
- */
- virtual void setListenerLocation(const AUD_Vector3& location)=0;
-
- /**
- * Retrieves the listener velocity.
- * \return The listener velocity.
- */
- virtual AUD_Vector3 getListenerVelocity() const=0;
-
- /**
- * Sets the listener velocity.
- * \param velocity The new velocity.
- */
- virtual void setListenerVelocity(const AUD_Vector3& velocity)=0;
-
- /**
- * Retrieves the listener orientation.
- * \return The listener orientation as quaternion.
- */
- virtual AUD_Quaternion getListenerOrientation() const=0;
-
- /**
- * Sets the listener orientation.
- * \param orientation The new orientation as quaternion.
- */
- virtual void setListenerOrientation(const AUD_Quaternion& orientation)=0;
-
-
- /**
- * Retrieves the speed of sound.
- * This value is needed for doppler effect calculation.
- * \return The speed of sound.
- */
- virtual float getSpeedOfSound() const=0;
-
- /**
- * Sets the speed of sound.
- * This value is needed for doppler effect calculation.
- * \param speed The new speed of sound.
- */
- virtual void setSpeedOfSound(float speed)=0;
-
- /**
- * Retrieves the doppler factor.
- * This value is a scaling factor for the velocity vectors of sources and
- * listener which is used while calculating the doppler effect.
- * \return The doppler factor.
- */
- virtual float getDopplerFactor() const=0;
-
- /**
- * Sets the doppler factor.
- * This value is a scaling factor for the velocity vectors of sources and
- * listener which is used while calculating the doppler effect.
- * \param factor The new doppler factor.
- */
- virtual void setDopplerFactor(float factor)=0;
-
- /**
- * Retrieves the distance model.
- * \return The distance model.
- */
- virtual AUD_DistanceModel getDistanceModel() const=0;
-
- /**
- * Sets the distance model.
- * \param model distance model.
- */
- virtual void setDistanceModel(AUD_DistanceModel model)=0;
-};
-
-#endif //__AUD_I3DDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
deleted file mode 100644
index a7f9a985ce4..00000000000
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_IDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IDEVICE_H__
-#define __AUD_IDEVICE_H__
-
-#include "AUD_Space.h"
-#include "AUD_IFactory.h"
-#include "AUD_IReader.h"
-#include "AUD_IHandle.h"
-#include "AUD_ILockable.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This class represents an output device for sound sources.
- * Output devices may be several backends such as plattform independand like
- * SDL or OpenAL or plattform specific like DirectSound, but they may also be
- * files, RAM buffers or other types of streams.
- * \warning Thread safety must be insured so that no reader is beeing called
- * twice at the same time.
- */
-class AUD_IDevice : public AUD_ILockable
-{
-public:
- /**
- * Destroys the device.
- */
- virtual ~AUD_IDevice() {}
-
- /**
- * Returns the specification of the device.
- */
- virtual AUD_DeviceSpecs getSpecs() const=0;
-
- /**
- * Plays a sound source.
- * \param reader The reader to play.
- * \param keep When keep is true the sound source will not be deleted but
- * set to paused when its end has been reached.
- * \return Returns a handle with which the playback can be controlled.
- * This is NULL if the sound couldn't be played back.
- * \exception AUD_Exception Thrown if there's an unexpected (from the
- * device side) error during creation of the reader.
- */
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false)=0;
-
- /**
- * Plays a sound source.
- * \param factory The factory to create the reader for the sound source.
- * \param keep When keep is true the sound source will not be deleted but
- * set to paused when its end has been reached.
- * \return Returns a handle with which the playback can be controlled.
- * This is NULL if the sound couldn't be played back.
- * \exception AUD_Exception Thrown if there's an unexpected (from the
- * device side) error during creation of the reader.
- */
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false)=0;
-
- /**
- * Stops all playing sounds.
- */
- virtual void stopAll()=0;
-
- /**
- * Locks the device.
- * Used to make sure that between lock and unlock, no buffers are read, so
- * that it is possible to start, resume, pause, stop or seek several
- * playback handles simultaneously.
- * \warning Make sure the locking time is as small as possible to avoid
- * playback delays that result in unexpected noise and cracks.
- */
- virtual void lock()=0;
-
- /**
- * Unlocks the previously locked device.
- */
- virtual void unlock()=0;
-
- /**
- * Retrieves the overall device volume.
- * \return The overall device volume.
- */
- virtual float getVolume() const=0;
-
- /**
- * Sets the overall device volume.
- * \param handle The sound handle.
- * \param volume The overall device volume.
- */
- virtual void setVolume(float volume)=0;
-};
-
-#endif //AUD_IDevice
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
deleted file mode 100644
index 75103963c68..00000000000
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_IFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IFACTORY_H__
-#define __AUD_IFACTORY_H__
-
-#include "AUD_Space.h"
-#include "AUD_IReader.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This class represents a type of sound source and saves the necessary values
- * for it. It is able to create a reader that is actually usable for playback
- * of the respective sound source through the factory method createReader.
- */
-class AUD_IFactory
-{
-public:
- /**
- * Destroys the factory.
- */
- virtual ~AUD_IFactory() {}
-
- /**
- * Creates a reader for playback of the sound source.
- * \return A pointer to an AUD_IReader object or NULL if there has been an
- * error.
- * \exception AUD_Exception An exception may be thrown if there has been
- * a more unexpected error during reader creation.
- */
- virtual boost::shared_ptr<AUD_IReader> createReader()=0;
-};
-
-#endif //__AUD_IFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ILockable.h b/intern/audaspace/intern/AUD_ILockable.h
deleted file mode 100644
index 9bc417504fe..00000000000
--- a/intern/audaspace/intern/AUD_ILockable.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef AUD_ILOCKABLE_H
-#define AUD_ILOCKABLE_H
-
-/**
- * This class provides an interface for lockable objects.
- * The main reason for this interface is to be used with AUD_MutexLock.
- */
-class AUD_ILockable
-{
-public:
- /**
- * Locks the object.
- */
- virtual void lock()=0;
- /**
- * Unlocks the previously locked object.
- */
- virtual void unlock()=0;
-};
-
-#endif // AUD_ILOCKABLE_H
diff --git a/intern/audaspace/intern/AUD_IWriter.h b/intern/audaspace/intern/AUD_IWriter.h
deleted file mode 100644
index 5406577dd50..00000000000
--- a/intern/audaspace/intern/AUD_IWriter.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_IWriter.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IWRITER_H__
-#define __AUD_IWRITER_H__
-
-#include "AUD_Space.h"
-
-/**
- * This class represents a sound sink where audio data can be written to.
- */
-class AUD_IWriter
-{
-public:
- /**
- * Destroys the writer.
- */
- virtual ~AUD_IWriter() {}
-
- /**
- * Returns how many samples have been written so far.
- * \return The writing position as sample count. May be negative if unknown.
- */
- virtual int getPosition() const=0;
-
- /**
- * Returns the specification of the audio data being written into the sink.
- * \return The AUD_DeviceSpecs structure.
- * \note Regardless of the format the input still has to be float!
- */
- virtual AUD_DeviceSpecs getSpecs() const=0;
-
- /**
- * Request to write the next length samples out into the sink.
- * \param length The count of samples to write.
- * \param buffer The pointer to the buffer containing the data.
- */
- virtual void write(unsigned int length, sample_t* buffer)=0;
-};
-
-#endif //__AUD_IWRITER_H__
diff --git a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp b/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
deleted file mode 100644
index 188960f986f..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_JOSResampleFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_JOSResampleFactory.h"
-#include "AUD_JOSResampleReader.h"
-
-AUD_JOSResampleFactory::AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_JOSResampleFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_JOSResampleReader(getReader(), m_specs.specs));
-}
diff --git a/intern/audaspace/intern/AUD_JOSResampleFactory.h b/intern/audaspace/intern/AUD_JOSResampleFactory.h
deleted file mode 100644
index b6c2961c88a..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_JOSResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_JOSRESAMPLEFACTORY_H__
-#define __AUD_JOSRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that does Julius O. Smith's resampling algorithm.
- */
-class AUD_JOSResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_JOSResampleFactory(const AUD_JOSResampleFactory&);
- AUD_JOSResampleFactory& operator=(const AUD_JOSResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_JOSRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.h b/intern/audaspace/intern/AUD_JOSResampleReader.h
deleted file mode 100644
index fb68e4dc9f5..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleReader.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_JOSResampleReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_JOSRESAMPLEREADER_H__
-#define __AUD_JOSRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This resampling reader uses Julius O. Smith's resampling algorithm.
- */
-class AUD_JOSResampleReader : public AUD_ResampleReader
-{
-private:
- typedef void (AUD_JOSResampleReader::*AUD_resample_f)(double target_factor, int length, sample_t* buffer);
-
- /**
- * The half filter length.
- */
- static const int m_len;
-
- /**
- * The sample step size for the filter.
- */
- static const int m_L;
-
- /**
- * The filter coefficients.
- */
- static const float m_coeff[];
-
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The sample position in the cache.
- */
- unsigned int m_n;
-
- /**
- * The subsample position in the cache.
- */
- double m_P;
-
- /**
- * The input data buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * Double buffer for the sums.
- */
- AUD_Buffer m_sums;
-
- /**
- * How many samples in the cache are valid.
- */
- int m_cache_valid;
-
- /**
- * Resample function.
- */
- AUD_resample_f m_resample;
-
- /**
- * Last resampling factor.
- */
- double m_last_factor;
-
- // hide copy constructor and operator=
- AUD_JOSResampleReader(const AUD_JOSResampleReader&);
- AUD_JOSResampleReader& operator=(const AUD_JOSResampleReader&);
-
- /**
- * Resets the resampler to its initial state.
- */
- void reset();
-
- /**
- * Updates the buffer to be as small as possible for the coming reading.
- * \param size The size of samples to be read.
- * \param factor The next resampling factor.
- * \param samplesize The size of a sample.
- */
- void updateBuffer(int size, double factor, int samplesize);
-
- void resample(double target_factor, int length, sample_t* buffer);
- void resample_mono(double target_factor, int length, sample_t* buffer);
- void resample_stereo(double target_factor, int length, sample_t* buffer);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_JOSRESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
deleted file mode 100644
index cd573f1047c..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_LinearResampleFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_LinearResampleFactory.h"
-#include "AUD_LinearResampleReader.h"
-
-AUD_LinearResampleFactory::AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LinearResampleFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_LinearResampleReader(getReader(), m_specs.specs));
-}
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
deleted file mode 100644
index ceb29ef2edd..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_LinearResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_LINEARRESAMPLEFACTORY_H__
-#define __AUD_LINEARRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that does simple linear resampling.
- */
-class AUD_LinearResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_LinearResampleFactory(const AUD_LinearResampleFactory&);
- AUD_LinearResampleFactory& operator=(const AUD_LinearResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_LINEARRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
deleted file mode 100644
index b342b8f31fb..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_LinearResampleReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_LinearResampleReader.h"
-
-#include <cmath>
-#include <cstring>
-
-#define CC m_channels + channel
-
-AUD_LinearResampleReader::AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader,
- AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(reader->getSpecs().channels),
- m_cache_pos(0),
- m_cache_ok(false)
-{
- specs.channels = m_channels;
- m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
-}
-
-void AUD_LinearResampleReader::seek(int position)
-{
- position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
- m_reader->seek(position);
- m_cache_ok = false;
- m_cache_pos = 0;
-}
-
-int AUD_LinearResampleReader::getLength() const
-{
- return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
-}
-
-int AUD_LinearResampleReader::getPosition() const
-{
- return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 1 : 0))
- * m_rate / m_reader->getSpecs().rate);
-}
-
-AUD_Specs AUD_LinearResampleReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.rate = m_rate;
- return specs;
-}
-
-void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- if(length == 0)
- return;
-
- AUD_Specs specs = m_reader->getSpecs();
-
- int samplesize = AUD_SAMPLE_SIZE(specs);
- int size = length;
- float factor = m_rate / m_reader->getSpecs().rate;
- float spos = 0.0f;
- sample_t low, high;
- eos = false;
-
- // check for channels changed
-
- if(specs.channels != m_channels)
- {
- m_cache.resize(2 * samplesize);
- m_channels = specs.channels;
- m_cache_ok = false;
- }
-
- if(factor == 1 && (!m_cache_ok || m_cache_pos == 1))
- {
- // can read directly!
- m_reader->read(length, eos, buffer);
-
- if(length > 0)
- {
- memcpy(m_cache.getBuffer() + m_channels, buffer + m_channels * (length - 1), samplesize);
- m_cache_pos = 1;
- m_cache_ok = true;
- }
-
- return;
- }
-
- int len;
- sample_t* buf;
-
- if(m_cache_ok)
- {
- int need = ceil(length / factor + m_cache_pos) - 1;
-
- len = need;
-
- m_buffer.assureSize((len + 2) * samplesize);
- buf = m_buffer.getBuffer();
-
- memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
- m_reader->read(len, eos, buf + 2 * m_channels);
-
- if(len < need)
- length = floor((len + 1 - m_cache_pos) * factor);
- }
- else
- {
- m_cache_pos = 1 - 1 / factor;
-
- int need = ceil(length / factor + m_cache_pos);
-
- len = need;
-
- m_buffer.assureSize((len + 1) * samplesize);
- buf = m_buffer.getBuffer();
-
- memset(buf, 0, samplesize);
- m_reader->read(len, eos, buf + m_channels);
-
- if(len == 0)
- {
- length = 0;
- return;
- }
-
- if(len < need)
- {
- length = floor((len - m_cache_pos) * factor);
- }
-
- m_cache_ok = true;
- }
-
- if(length == 0)
- return;
-
- for(int channel = 0; channel < m_channels; channel++)
- {
- for(int i = 0; i < length; i++)
- {
- spos = (i + 1) / factor + m_cache_pos;
-
- low = buf[(int)floor(spos) * CC];
- high = buf[(int)ceil(spos) * CC];
-
- buffer[i * CC] = low + (spos - floor(spos)) * (high - low);
- }
- }
-
- if(floor(spos) == spos)
- {
- memcpy(m_cache.getBuffer() + m_channels, buf + int(floor(spos)) * m_channels, samplesize);
- m_cache_pos = 1;
- }
- else
- {
- memcpy(m_cache.getBuffer(), buf + int(floor(spos)) * m_channels, 2 * samplesize);
- m_cache_pos = spos - floor(spos);
- }
-
- eos &= length < size;
-}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
deleted file mode 100644
index 9beea251c07..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleReader.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_LinearResampleReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_LINEARRESAMPLEREADER_H__
-#define __AUD_LINEARRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This resampling reader does simple first-order hold resampling.
- */
-class AUD_LinearResampleReader : public AUD_ResampleReader
-{
-private:
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The position in the cache.
- */
- float m_cache_pos;
-
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The input caching buffer.
- */
- AUD_Buffer m_cache;
-
- /**
- * Whether the cache contains valid data.
- */
- bool m_cache_ok;
-
- // hide copy constructor and operator=
- AUD_LinearResampleReader(const AUD_LinearResampleReader&);
- AUD_LinearResampleReader& operator=(const AUD_LinearResampleReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LINEARRESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_Mixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
deleted file mode 100644
index 78dfaddd27a..00000000000
--- a/intern/audaspace/intern/AUD_Mixer.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Mixer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_Mixer.h"
-#include "AUD_IReader.h"
-
-#include <cstring>
-
-AUD_Mixer::AUD_Mixer(AUD_DeviceSpecs specs) :
- m_specs(specs)
-{
- switch(m_specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
-
-#ifdef __BIG_ENDIAN__
- m_convert = AUD_convert_float_s24_be;
-#else
- m_convert = AUD_convert_float_s24_le;
-#endif
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
-}
-
-AUD_DeviceSpecs AUD_Mixer::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_Mixer::setSpecs(AUD_Specs specs)
-{
- m_specs.specs = specs;
-}
-
-void AUD_Mixer::clear(int length)
-{
- m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
-
- m_length = length;
-
- memset(m_buffer.getBuffer(), 0, length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
-}
-
-void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume)
-{
- sample_t* out = m_buffer.getBuffer();
-
- length = (AUD_MIN(m_length, length + start) - start) * m_specs.channels;
- start *= m_specs.channels;
-
- for(int i = 0; i < length; i++)
- out[i + start] += buffer[i] * volume;
-}
-
-void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume_to, float volume_from)
-{
- sample_t* out = m_buffer.getBuffer();
-
- length = (std::min(m_length, length + start) - start);
-
- for(int i = 0; i < length; i++)
- {
- float volume = volume_from * (1.0f - i / float(length)) + volume_to * (i / float(length));
-
- for(int c = 0; c < m_specs.channels; c++)
- out[(i + start) * m_specs.channels + c] += buffer[i * m_specs.channels + c] * volume;
- }
-}
-
-void AUD_Mixer::read(data_t* buffer, float volume)
-{
- sample_t* out = m_buffer.getBuffer();
-
- for(int i = 0; i < m_length * m_specs.channels; i++)
- out[i] *= volume;
-
- m_convert(buffer, (data_t*) out, m_length * m_specs.channels);
-}
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
deleted file mode 100644
index 0735fee715b..00000000000
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Mixer.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_MIXER_H__
-#define __AUD_MIXER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-class AUD_IReader;
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This abstract class is able to mix audiosignals with same channel count
- * and sample rate and convert it to a specific output format.
- */
-class AUD_Mixer
-{
-protected:
- /**
- * The output specification.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The length of the mixing buffer.
- */
- int m_length;
-
- /**
- * The mixing buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
-public:
- /**
- * Creates the mixer.
- */
- AUD_Mixer(AUD_DeviceSpecs specs);
-
- /**
- * Destroys the mixer.
- */
- virtual ~AUD_Mixer() {}
-
- /**
- * Returns the target specification for superposing.
- * \return The target specification.
- */
- AUD_DeviceSpecs getSpecs() const;
-
- /**
- * Sets the target specification for superposing.
- * \param specs The target specification.
- */
- void setSpecs(AUD_Specs specs);
-
- /**
- * Mixes a buffer.
- * \param buffer The buffer to superpose.
- * \param start The start sample of the buffer.
- * \param length The length of the buffer in samples.
- * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
- */
- void mix(sample_t* buffer, int start, int length, float volume);
-
- void mix(sample_t* buffer, int start, int length, float volume_to, float volume_from);
-
- /**
- * Writes the mixing buffer into an output buffer.
- * \param buffer The target buffer for superposing.
- * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
- */
- void read(data_t* buffer, float volume);
-
- /**
- * Clears the mixing buffer.
- * \param length The length of the buffer in samples.
- */
- void clear(int length);
-};
-
-#endif //__AUD_MIXER_H__
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
deleted file mode 100644
index f3f00ea2cb6..00000000000
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_MixerFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_MixerFactory.h"
-#include "AUD_IReader.h"
-
-boost::shared_ptr<AUD_IReader> AUD_MixerFactory::getReader() const
-{
- return m_factory->createReader();
-}
-
-AUD_MixerFactory::AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- m_specs(specs), m_factory(factory)
-{
-}
-
-AUD_DeviceSpecs AUD_MixerFactory::getSpecs() const
-{
- return m_specs;
-}
-
-boost::shared_ptr<AUD_IFactory> AUD_MixerFactory::getFactory() const
-{
- return m_factory;
-}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
deleted file mode 100644
index 1d2b6a4cc91..00000000000
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_MixerFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_MIXERFACTORY_H__
-#define __AUD_MIXERFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory is a base class for all mixer factories.
- */
-class AUD_MixerFactory : public AUD_IFactory
-{
-protected:
- /**
- * The target specification for resampling.
- */
- const AUD_DeviceSpecs m_specs;
-
- /**
- * If there is no reader it is created out of this factory.
- */
- boost::shared_ptr<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 to mix.
- */
- boost::shared_ptr<AUD_IReader> getReader() const;
-
-public:
- /**
- * Creates a new factory.
- * \param factory The factory to create the readers to mix out of.
- * \param specs The target specification.
- */
- AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- /**
- * Returns the target specification for resampling.
- */
- AUD_DeviceSpecs getSpecs() const;
-
- /**
- * Returns the saved factory.
- * \return The factory.
- */
- boost::shared_ptr<AUD_IFactory> getFactory() const;
-};
-
-#endif //__AUD_MIXERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_MutexLock.h b/intern/audaspace/intern/AUD_MutexLock.h
deleted file mode 100644
index b6f6d2b4334..00000000000
--- a/intern/audaspace/intern/AUD_MutexLock.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef AUD_MUTEXLOCK_H
-#define AUD_MUTEXLOCK_H
-
-#include "AUD_ILockable.h"
-
-class AUD_MutexLock
-{
-public:
- inline AUD_MutexLock(AUD_ILockable& lockable) :
- lockable(lockable)
- {
- lockable.lock();
- }
-
- inline ~AUD_MutexLock()
- {
- lockable.unlock();
- }
-
-private:
- AUD_ILockable& lockable;
-};
-
-#endif // AUD_MUTEXLOCK_H
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
deleted file mode 100644
index 98a0d324c61..00000000000
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_NULLDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include <limits>
-
-#include "AUD_NULLDevice.h"
-
-AUD_NULLDevice::AUD_NULLHandle::AUD_NULLHandle()
-{
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::pause()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::resume()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::stop()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::getKeep()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setKeep(bool keep)
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::seek(float position)
-{
- return false;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getPosition()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-AUD_Status AUD_NULLDevice::AUD_NULLHandle::getStatus()
-{
- return AUD_STATUS_INVALID;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getVolume()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setVolume(float volume)
-{
- return false;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getPitch()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setPitch(float pitch)
-{
- return false;
-}
-
-int AUD_NULLDevice::AUD_NULLHandle::getLoopCount()
-{
- return 0;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setLoopCount(int count)
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setStopCallback(stopCallback callback, void* data)
-{
- return false;
-}
-
-AUD_NULLDevice::AUD_NULLDevice()
-{
-}
-
-AUD_NULLDevice::~AUD_NULLDevice()
-{
-}
-
-AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
-{
- AUD_DeviceSpecs specs;
- specs.channels = AUD_CHANNELS_INVALID;
- specs.format = AUD_FORMAT_INVALID;
- specs.rate = AUD_RATE_INVALID;
- return specs;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
-}
-
-void AUD_NULLDevice::stopAll()
-{
-}
-
-void AUD_NULLDevice::lock()
-{
-}
-
-void AUD_NULLDevice::unlock()
-{
-}
-
-float AUD_NULLDevice::getVolume() const
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-void AUD_NULLDevice::setVolume(float volume)
-{
-}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
deleted file mode 100644
index ae1435bbeea..00000000000
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_NULLDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_NULLDEVICE_H__
-#define __AUD_NULLDEVICE_H__
-
-#include "AUD_IReader.h"
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-
-/**
- * This device plays nothing.
- */
-class AUD_NULLDevice : public AUD_IDevice
-{
-private:
- class AUD_NULLHandle : public AUD_IHandle
- {
- public:
-
- AUD_NULLHandle();
-
- virtual ~AUD_NULLHandle() {}
- virtual bool pause();
- virtual bool resume();
- virtual bool stop();
- virtual bool getKeep();
- virtual bool setKeep(bool keep);
- virtual bool seek(float position);
- virtual float getPosition();
- virtual AUD_Status getStatus();
- virtual float getVolume();
- virtual bool setVolume(float volume);
- virtual float getPitch();
- virtual bool setPitch(float pitch);
- virtual int getLoopCount();
- virtual bool setLoopCount(int count);
- virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- };
-public:
- /**
- * Creates a new NULL device.
- */
- AUD_NULLDevice();
-
- virtual ~AUD_NULLDevice();
-
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
- virtual void stopAll();
- virtual void lock();
- virtual void unlock();
- virtual float getVolume() const;
- virtual void setVolume(float volume);
-};
-
-#endif //__AUD_NULLDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
deleted file mode 100644
index bab6ce4f001..00000000000
--- a/intern/audaspace/intern/AUD_ReadDevice.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ReadDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ReadDevice.h"
-#include "AUD_IReader.h"
-
-#include <cstring>
-
-AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs) :
- m_playing(false)
-{
- m_specs = specs;
-
- create();
-}
-
-AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs) :
- m_playing(false)
-{
- m_specs.specs = specs;
- m_specs.format = AUD_FORMAT_FLOAT32;
-
- create();
-}
-
-AUD_ReadDevice::~AUD_ReadDevice()
-{
- destroy();
-}
-
-bool AUD_ReadDevice::read(data_t* buffer, int length)
-{
- if(m_playing)
- mix(buffer, length);
- else
- if(m_specs.format == AUD_FORMAT_U8)
- memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
- else
- memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
- return m_playing;
-}
-
-void AUD_ReadDevice::changeSpecs(AUD_Specs specs)
-{
- if(!AUD_COMPARE_SPECS(specs, m_specs.specs))
- setSpecs(specs);
-}
-
-void AUD_ReadDevice::playing(bool playing)
-{
- m_playing = playing;
-}
diff --git a/intern/audaspace/intern/AUD_ReadDevice.h b/intern/audaspace/intern/AUD_ReadDevice.h
deleted file mode 100644
index 0f077fe5d7e..00000000000
--- a/intern/audaspace/intern/AUD_ReadDevice.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ReadDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_READDEVICE_H__
-#define __AUD_READDEVICE_H__
-
-#include "AUD_SoftwareDevice.h"
-
-/**
- * This device enables to let the user read raw data out of it.
- */
-class AUD_ReadDevice : public AUD_SoftwareDevice
-{
-private:
- /**
- * Whether the device currently.
- */
- bool m_playing;
-
- // hide copy constructor and operator=
- AUD_ReadDevice(const AUD_ReadDevice&);
- AUD_ReadDevice& operator=(const AUD_ReadDevice&);
-
-protected:
- virtual void playing(bool playing);
-
-public:
- /**
- * Creates a new read device.
- * \param specs The wanted audio specification.
- */
- AUD_ReadDevice(AUD_DeviceSpecs specs);
-
- /**
- * Creates a new read device.
- * \param specs The wanted audio specification.
- */
- AUD_ReadDevice(AUD_Specs specs);
-
- /**
- * Closes the device.
- */
- virtual ~AUD_ReadDevice();
-
- /**
- * Reads the next bytes into the supplied buffer.
- * \param buffer The target buffer.
- * \param length The length in samples to be filled.
- * \return True if the reading succeeded, false if there are no sounds
- * played back currently, in that case the buffer is filled with
- * silence.
- */
- bool read(data_t* buffer, int length);
-
- /**
- * Changes the output specification.
- * \param specs The new audio data specification.
- */
- void changeSpecs(AUD_Specs specs);
-};
-
-#endif //__AUD_READDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_ResampleFactory.h b/intern/audaspace/intern/AUD_ResampleFactory.h
deleted file mode 100644
index 11f8dc15f03..00000000000
--- a/intern/audaspace/intern/AUD_ResampleFactory.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_RESAMPLEFACTORY_H__
-#define __AUD_RESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-typedef AUD_MixerFactory AUD_ResampleFactory;
-
-#endif //__AUD_RESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ResampleReader.cpp b/intern/audaspace/intern/AUD_ResampleReader.cpp
deleted file mode 100644
index 4b247ffd862..00000000000
--- a/intern/audaspace/intern/AUD_ResampleReader.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ResampleReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ResampleReader.h"
-
-AUD_ResampleReader::AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate) :
- AUD_EffectReader(reader), m_rate(rate)
-{
-}
-
-void AUD_ResampleReader::setRate(AUD_SampleRate rate)
-{
- m_rate = rate;
-}
-
-AUD_SampleRate AUD_ResampleReader::getRate()
-{
- return m_rate;
-}
diff --git a/intern/audaspace/intern/AUD_ResampleReader.h b/intern/audaspace/intern/AUD_ResampleReader.h
deleted file mode 100644
index 7e21989bfa8..00000000000
--- a/intern/audaspace/intern/AUD_ResampleReader.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_ResampleReader.h
- * \ingroup audaspaceintern
- */
-
-#ifndef __AUD_RESAMPLEREADER_H__
-#define __AUD_RESAMPLEREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This is the base class for all resampling readers.
- */
-class AUD_ResampleReader : public AUD_EffectReader
-{
-protected:
- /**
- * The target sampling rate.
- */
- AUD_SampleRate m_rate;
-
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param rate The target sampling rate.
- */
- AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate);
-
-public:
- /**
- * Sets the sample rate.
- * \param rate The target sampling rate.
- */
- virtual void setRate(AUD_SampleRate rate);
-
- /**
- * Retrieves the sample rate.
- * \return The target sampling rate.
- */
- virtual AUD_SampleRate getRate();
-};
-
-#endif // __AUD_RESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp
deleted file mode 100644
index ddcf97e2ea1..00000000000
--- a/intern/audaspace/intern/AUD_Sequencer.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Sequencer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_Sequencer.h"
-#include "AUD_SequencerReader.h"
-#include "AUD_3DMath.h"
-#include "AUD_MutexLock.h"
-
-AUD_Sequencer::AUD_Sequencer(AUD_Specs specs, float fps, bool muted) :
- m_specs(specs),
- m_status(0),
- m_entry_status(0),
- m_id(0),
- m_muted(muted),
- m_fps(fps),
- m_speed_of_sound(343.3f),
- m_doppler_factor(1),
- m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
- m_volume(1, 1.0f),
- m_location(3),
- m_orientation(4)
-{
- AUD_Quaternion q;
- m_orientation.write(q.get());
- float f = 1;
- m_volume.write(&f);
-
- 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_Sequencer::~AUD_Sequencer()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_Sequencer::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_Sequencer::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-void AUD_Sequencer::setSpecs(AUD_Specs specs)
-{
- AUD_MutexLock lock(*this);
-
- m_specs = specs;
- m_status++;
-}
-
-void AUD_Sequencer::setFPS(float fps)
-{
- AUD_MutexLock lock(*this);
-
- m_fps = fps;
-}
-
-void AUD_Sequencer::mute(bool muted)
-{
- AUD_MutexLock lock(*this);
-
- m_muted = muted;
-}
-
-bool AUD_Sequencer::getMute() const
-{
- return m_muted;
-}
-
-float AUD_Sequencer::getSpeedOfSound() const
-{
- return m_speed_of_sound;
-}
-
-void AUD_Sequencer::setSpeedOfSound(float speed)
-{
- AUD_MutexLock lock(*this);
-
- m_speed_of_sound = speed;
- m_status++;
-}
-
-float AUD_Sequencer::getDopplerFactor() const
-{
- return m_doppler_factor;
-}
-
-void AUD_Sequencer::setDopplerFactor(float factor)
-{
- AUD_MutexLock lock(*this);
-
- m_doppler_factor = factor;
- m_status++;
-}
-
-AUD_DistanceModel AUD_Sequencer::getDistanceModel() const
-{
- return m_distance_model;
-}
-
-void AUD_Sequencer::setDistanceModel(AUD_DistanceModel model)
-{
- AUD_MutexLock lock(*this);
-
- m_distance_model = model;
- m_status++;
-}
-
-AUD_AnimateableProperty* AUD_Sequencer::getAnimProperty(AUD_AnimateablePropertyType type)
-{
- switch(type)
- {
- case AUD_AP_VOLUME:
- return &m_volume;
- case AUD_AP_LOCATION:
- return &m_location;
- case AUD_AP_ORIENTATION:
- return &m_orientation;
- default:
- return NULL;
- }
-}
-
-boost::shared_ptr<AUD_SequencerEntry> AUD_Sequencer::add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip)
-{
- AUD_MutexLock lock(*this);
-
- boost::shared_ptr<AUD_SequencerEntry> entry = boost::shared_ptr<AUD_SequencerEntry>(new AUD_SequencerEntry(sound, begin, end, skip, m_id++));
-
- m_entries.push_back(entry);
- m_entry_status++;
-
- return entry;
-}
-
-void AUD_Sequencer::remove(boost::shared_ptr<AUD_SequencerEntry> entry)
-{
- AUD_MutexLock lock(*this);
-
- m_entries.remove(entry);
- m_entry_status++;
-}
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.cpp b/intern/audaspace/intern/AUD_SequencerEntry.cpp
deleted file mode 100644
index 6ef8479cdb8..00000000000
--- a/intern/audaspace/intern/AUD_SequencerEntry.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SequencerEntry.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SequencerEntry.h"
-#include "AUD_SequencerReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cmath>
-#include <limits>
-
-AUD_SequencerEntry::AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip, int id) :
- m_status(0),
- m_pos_status(1),
- m_sound_status(0),
- m_id(id),
- m_sound(sound),
- m_begin(begin),
- m_end(end),
- m_skip(skip),
- m_muted(false),
- m_relative(true),
- m_volume_max(1.0f),
- m_volume_min(0),
- m_distance_max(std::numeric_limits<float>::max()),
- m_distance_reference(1.0f),
- m_attenuation(1.0f),
- m_cone_angle_outer(360),
- m_cone_angle_inner(360),
- m_cone_volume_outer(0),
- m_volume(1, 1.0f),
- m_pitch(1, 1.0f),
- m_location(3),
- m_orientation(4)
-{
- AUD_Quaternion q;
- m_orientation.write(q.get());
- float f = 1;
- m_volume.write(&f);
- m_pitch.write(&f);
-
- 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_SequencerEntry::~AUD_SequencerEntry()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_SequencerEntry::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SequencerEntry::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-void AUD_SequencerEntry::setSound(boost::shared_ptr<AUD_IFactory> sound)
-{
- AUD_MutexLock lock(*this);
-
- if(m_sound.get() != sound.get())
- {
- m_sound = sound;
- m_sound_status++;
- }
-}
-
-void AUD_SequencerEntry::move(float begin, float end, float skip)
-{
- AUD_MutexLock lock(*this);
-
- if(m_begin != begin || m_skip != skip || m_end != end)
- {
- m_begin = begin;
- m_skip = skip;
- m_end = end;
- m_pos_status++;
- }
-}
-
-void AUD_SequencerEntry::mute(bool mute)
-{
- AUD_MutexLock lock(*this);
-
- m_muted = mute;
-}
-
-int AUD_SequencerEntry::getID() const
-{
- return m_id;
-}
-
-AUD_AnimateableProperty* AUD_SequencerEntry::getAnimProperty(AUD_AnimateablePropertyType type)
-{
- switch(type)
- {
- case AUD_AP_VOLUME:
- return &m_volume;
- case AUD_AP_PITCH:
- return &m_pitch;
- case AUD_AP_PANNING:
- return &m_panning;
- case AUD_AP_LOCATION:
- return &m_location;
- case AUD_AP_ORIENTATION:
- return &m_orientation;
- default:
- return NULL;
- }
-}
-
-void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float distance_max,
- float distance_reference, float attenuation, float cone_angle_outer,
- float cone_angle_inner, float cone_volume_outer)
-{
- AUD_MutexLock lock(*this);
-
- if(volume_max != m_volume_max)
- {
- m_volume_max = volume_max;
- m_status++;
- }
-
- if(volume_min != m_volume_min)
- {
- m_volume_min = volume_min;
- m_status++;
- }
-
- if(distance_max != m_distance_max)
- {
- m_distance_max = distance_max;
- m_status++;
- }
-
- if(distance_reference != m_distance_reference)
- {
- m_distance_reference = distance_reference;
- m_status++;
- }
-
- if(attenuation != m_attenuation)
- {
- m_attenuation = attenuation;
- m_status++;
- }
-
- if(cone_angle_outer != m_cone_angle_outer)
- {
- m_cone_angle_outer = cone_angle_outer;
- m_status++;
- }
-
- if(cone_angle_inner != m_cone_angle_inner)
- {
- m_cone_angle_inner = cone_angle_inner;
- m_status++;
- }
-
- if(cone_volume_outer != m_cone_volume_outer)
- {
- m_cone_volume_outer = cone_volume_outer;
- m_status++;
- }
-}
-
-bool AUD_SequencerEntry::isRelative()
-{
- return m_relative;
-}
-
-void AUD_SequencerEntry::setRelative(bool relative)
-{
- AUD_MutexLock lock(*this);
-
- if(m_relative != relative)
- {
- m_relative = relative;
- m_status++;
- }
-}
-
-float AUD_SequencerEntry::getVolumeMaximum()
-{
- return m_volume_max;
-}
-
-void AUD_SequencerEntry::setVolumeMaximum(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_volume_max = volume;
- m_status++;
-}
-
-float AUD_SequencerEntry::getVolumeMinimum()
-{
- return m_volume_min;
-}
-
-void AUD_SequencerEntry::setVolumeMinimum(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_volume_min = volume;
- m_status++;
-}
-
-float AUD_SequencerEntry::getDistanceMaximum()
-{
- return m_distance_max;
-}
-
-void AUD_SequencerEntry::setDistanceMaximum(float distance)
-{
- AUD_MutexLock lock(*this);
-
- m_distance_max = distance;
- m_status++;
-}
-
-float AUD_SequencerEntry::getDistanceReference()
-{
- return m_distance_reference;
-}
-
-void AUD_SequencerEntry::setDistanceReference(float distance)
-{
- AUD_MutexLock lock(*this);
-
- m_distance_reference = distance;
- m_status++;
-}
-
-float AUD_SequencerEntry::getAttenuation()
-{
- return m_attenuation;
-}
-
-void AUD_SequencerEntry::setAttenuation(float factor)
-{
- AUD_MutexLock lock(*this);
-
- m_attenuation = factor;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeAngleOuter()
-{
- return m_cone_angle_outer;
-}
-
-void AUD_SequencerEntry::setConeAngleOuter(float angle)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_angle_outer = angle;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeAngleInner()
-{
- return m_cone_angle_inner;
-}
-
-void AUD_SequencerEntry::setConeAngleInner(float angle)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_angle_inner = angle;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeVolumeOuter()
-{
- return m_cone_volume_outer;
-}
-
-void AUD_SequencerEntry::setConeVolumeOuter(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_volume_outer = volume;
- m_status++;
-}
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
deleted file mode 100644
index f6076603c2b..00000000000
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SequencerFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SequencerFactory.h"
-#include "AUD_SequencerReader.h"
-#include "AUD_3DMath.h"
-#include "AUD_MutexLock.h"
-
-AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted)
-{
- m_sequence = boost::shared_ptr<AUD_Sequencer>(new AUD_Sequencer(specs, fps, muted));
-}
-
-/*void AUD_SequencerFactory::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SequencerFactory::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}*/
-
-void AUD_SequencerFactory::setSpecs(AUD_Specs specs)
-{
- m_sequence->setSpecs(specs);
-}
-
-void AUD_SequencerFactory::setFPS(float fps)
-{
- m_sequence->setFPS(fps);
-}
-
-void AUD_SequencerFactory::mute(bool muted)
-{
- m_sequence->mute(muted);
-}
-
-bool AUD_SequencerFactory::getMute() const
-{
- return m_sequence->getMute();
-}
-
-float AUD_SequencerFactory::getSpeedOfSound() const
-{
- return m_sequence->getSpeedOfSound();
-}
-
-void AUD_SequencerFactory::setSpeedOfSound(float speed)
-{
- m_sequence->setSpeedOfSound(speed);
-}
-
-float AUD_SequencerFactory::getDopplerFactor() const
-{
- return m_sequence->getDopplerFactor();
-}
-
-void AUD_SequencerFactory::setDopplerFactor(float factor)
-{
- m_sequence->setDopplerFactor(factor);
-}
-
-AUD_DistanceModel AUD_SequencerFactory::getDistanceModel() const
-{
- return m_sequence->getDistanceModel();
-}
-
-void AUD_SequencerFactory::setDistanceModel(AUD_DistanceModel model)
-{
- m_sequence->setDistanceModel(model);
-}
-
-AUD_AnimateableProperty* AUD_SequencerFactory::getAnimProperty(AUD_AnimateablePropertyType type)
-{
- return m_sequence->getAnimProperty(type);
-}
-
-boost::shared_ptr<AUD_SequencerEntry> AUD_SequencerFactory::add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip)
-{
- return m_sequence->add(sound, begin, end, skip);
-}
-
-void AUD_SequencerFactory::remove(boost::shared_ptr<AUD_SequencerEntry> entry)
-{
- m_sequence->remove(entry);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createQualityReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence, true));
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence));
-}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
deleted file mode 100644
index aef93cd3896..00000000000
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SequencerReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SequencerReader.h"
-#include "AUD_MutexLock.h"
-
-typedef std::list<boost::shared_ptr<AUD_SequencerHandle> >::iterator AUD_HandleIterator;
-typedef std::list<boost::shared_ptr<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
-
-AUD_SequencerReader::AUD_SequencerReader(boost::shared_ptr<AUD_Sequencer> sequence, bool quality) :
- m_position(0), m_device(sequence->m_specs), m_sequence(sequence), m_status(0), m_entry_status(0)
-{
- m_device.setQuality(quality);
-}
-
-AUD_SequencerReader::~AUD_SequencerReader()
-{
-}
-
-bool AUD_SequencerReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SequencerReader::seek(int position)
-{
- if(position < 0)
- return;
-
- m_position = position;
-
- for(AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
- {
- (*it)->seek(position / m_sequence->m_specs.rate);
- }
-}
-
-int AUD_SequencerReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SequencerReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SequencerReader::getSpecs() const
-{
- return m_sequence->m_specs;
-}
-
-void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_MutexLock lock(*m_sequence);
-
- if(m_sequence->m_status != m_status)
- {
- m_device.changeSpecs(m_sequence->m_specs);
- m_device.setSpeedOfSound(m_sequence->m_speed_of_sound);
- m_device.setDistanceModel(m_sequence->m_distance_model);
- m_device.setDopplerFactor(m_sequence->m_doppler_factor);
-
- m_status = m_sequence->m_status;
- }
-
- if(m_sequence->m_entry_status != m_entry_status)
- {
- std::list<boost::shared_ptr<AUD_SequencerHandle> > handles;
-
- AUD_HandleIterator hit = m_handles.begin();
- AUD_EntryIterator eit = m_sequence->m_entries.begin();
-
- int result;
- boost::shared_ptr<AUD_SequencerHandle> handle;
-
- while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
- {
- handle = *hit;
- boost::shared_ptr<AUD_SequencerEntry> entry = *eit;
-
- result = handle->compare(entry);
-
- if(result < 0)
- {
- try
- {
- handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(entry, m_device));
- handles.push_back(handle);
- }
- catch(AUD_Exception&)
- {
- }
- eit++;
- }
- else if(result == 0)
- {
- handles.push_back(handle);
- hit++;
- eit++;
- }
- else
- {
- handle->stop();
- hit++;
- }
- }
-
- while(hit != m_handles.end())
- {
- (*hit)->stop();
- hit++;
- }
-
- while(eit != m_sequence->m_entries.end())
- {
- try
- {
- handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(*eit, m_device));
- handles.push_back(handle);
- }
- catch(AUD_Exception&)
- {
- }
- eit++;
- }
-
- m_handles = handles;
-
- m_entry_status = m_sequence->m_entry_status;
- }
-
- AUD_Specs specs = m_sequence->m_specs;
- int pos = 0;
- float time = float(m_position) / float(specs.rate);
- float volume, frame;
- int len, cfra;
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
-
-
- while(pos < length)
- {
- frame = time * m_sequence->m_fps;
- cfra = int(floor(frame));
-
- len = int(ceil((cfra + 1) / m_sequence->m_fps * specs.rate)) - m_position;
- len = AUD_MIN(length - pos, len);
- len = AUD_MAX(len, 1);
-
- for(AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
- {
- (*it)->update(time, frame, m_sequence->m_fps);
- }
-
- m_sequence->m_volume.read(frame, &volume);
- if(m_sequence->m_muted)
- volume = 0.0f;
- m_device.setVolume(volume);
-
- m_sequence->m_orientation.read(frame, q.get());
- m_device.setListenerOrientation(q);
- m_sequence->m_location.read(frame, v.get());
- m_device.setListenerLocation(v);
- m_sequence->m_location.read(frame + 1, v2.get());
- v2 -= v;
- m_device.setListenerVelocity(v2 * m_sequence->m_fps);
-
- m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
-
- pos += len;
- time += float(len) / float(specs.rate);
- }
-
- m_position += length;
-
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h
deleted file mode 100644
index 6b3dbc9313e..00000000000
--- a/intern/audaspace/intern/AUD_SequencerReader.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SequencerReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SEQUENCERREADER_H__
-#define __AUD_SEQUENCERREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_Sequencer.h"
-#include "AUD_SequencerHandle.h"
-
-/**
- * This reader plays back sequenced entries.
- */
-class AUD_SequencerReader : public AUD_IReader
-{
-private:
- /**
- * The current position.
- */
- int m_position;
-
- /**
- * The read device used to mix the sounds correctly.
- */
- AUD_ReadDevice m_device;
-
- /**
- * Saves the sequence the reader belongs to.
- */
- boost::shared_ptr<AUD_Sequencer> m_sequence;
-
- /**
- * The list of playback handles for the entries.
- */
- std::list<boost::shared_ptr<AUD_SequencerHandle> > m_handles;
-
- /**
- * Last status read from the sequence.
- */
- int m_status;
-
- /**
- * Last entry status read from the sequence.
- */
- int m_entry_status;
-
- // hide copy constructor and operator=
- AUD_SequencerReader(const AUD_SequencerReader&);
- AUD_SequencerReader& operator=(const AUD_SequencerReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_SequencerReader(boost::shared_ptr<AUD_Sequencer> sequence, bool quality = false);
-
- /**
- * Destroys the reader.
- */
- ~AUD_SequencerReader();
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SEQUENCERREADER_H__
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
deleted file mode 100644
index 85034b316ca..00000000000
--- a/intern/audaspace/intern/AUD_SilenceFactory.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SilenceFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SilenceFactory.h"
-#include "AUD_SilenceReader.h"
-#include "AUD_Space.h"
-
-AUD_SilenceFactory::AUD_SilenceFactory()
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SilenceFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SilenceReader());
-}
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.h b/intern/audaspace/intern/AUD_SilenceFactory.h
deleted file mode 100644
index de62a2f94fc..00000000000
--- a/intern/audaspace/intern/AUD_SilenceFactory.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SilenceFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SILENCEFACTORY_H__
-#define __AUD_SILENCEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory creates a reader that plays silence.
- */
-class AUD_SilenceFactory : public AUD_IFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_SilenceFactory(const AUD_SilenceFactory&);
- AUD_SilenceFactory& operator=(const AUD_SilenceFactory&);
-
-public:
- /**
- * Creates a new silence factory.
- */
- AUD_SilenceFactory();
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SILENCEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SilenceReader.cpp b/intern/audaspace/intern/AUD_SilenceReader.cpp
deleted file mode 100644
index 5d7e83f7f09..00000000000
--- a/intern/audaspace/intern/AUD_SilenceReader.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SilenceReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SilenceReader.h"
-
-#include <cstring>
-
-AUD_SilenceReader::AUD_SilenceReader() :
- m_position(0)
-{
-}
-
-bool AUD_SilenceReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SilenceReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_SilenceReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SilenceReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SilenceReader::getSpecs() const
-{
- AUD_Specs specs;
- specs.rate = AUD_RATE_48000;
- specs.channels = AUD_CHANNELS_MONO;
- return specs;
-}
-
-void AUD_SilenceReader::read(int& length, bool& eos, sample_t* buffer)
-{
- memset(buffer, 0, length * sizeof(sample_t));
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SilenceReader.h b/intern/audaspace/intern/AUD_SilenceReader.h
deleted file mode 100644
index cac56a0861b..00000000000
--- a/intern/audaspace/intern/AUD_SilenceReader.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SilenceReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SILENCEREADER_H__
-#define __AUD_SILENCEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class is used for silence playback.
- * The signal generated is 44.1kHz mono.
- */
-class AUD_SilenceReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- // hide copy constructor and operator=
- AUD_SilenceReader(const AUD_SilenceReader&);
- AUD_SilenceReader& operator=(const AUD_SilenceReader&);
-
-public:
- /**
- * Creates a new reader.
- */
- AUD_SilenceReader();
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SILENCEREADER_H__
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
deleted file mode 100644
index 2b9742cc90c..00000000000
--- a/intern/audaspace/intern/AUD_SinusFactory.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SinusFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SinusFactory.h"
-#include "AUD_SinusReader.h"
-#include "AUD_Space.h"
-
-AUD_SinusFactory::AUD_SinusFactory(float frequency, AUD_SampleRate sampleRate) :
- m_frequency(frequency),
- m_sampleRate(sampleRate)
-{
-}
-
-float AUD_SinusFactory::getFrequency() const
-{
- return m_frequency;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SinusFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SinusReader(m_frequency, m_sampleRate));
-}
diff --git a/intern/audaspace/intern/AUD_SinusFactory.h b/intern/audaspace/intern/AUD_SinusFactory.h
deleted file mode 100644
index c8d409a4aff..00000000000
--- a/intern/audaspace/intern/AUD_SinusFactory.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SinusFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SINUSFACTORY_H__
-#define __AUD_SINUSFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory creates a reader that plays a sine tone.
- */
-class AUD_SinusFactory : public AUD_IFactory
-{
-private:
- /**
- * The frequence of the sine wave.
- */
- const float m_frequency;
-
- /**
- * The target sample rate for output.
- */
- const AUD_SampleRate m_sampleRate;
-
- // hide copy constructor and operator=
- AUD_SinusFactory(const AUD_SinusFactory&);
- AUD_SinusFactory& operator=(const AUD_SinusFactory&);
-
-public:
- /**
- * Creates a new sine factory.
- * \param frequency The desired frequency.
- * \param sampleRate The target sample rate for playback.
- */
- AUD_SinusFactory(float frequency,
- AUD_SampleRate sampleRate = AUD_RATE_48000);
-
- /**
- * Returns the frequency of the sine wave.
- */
- float getFrequency() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SINUSFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
deleted file mode 100644
index 2e89126bd7b..00000000000
--- a/intern/audaspace/intern/AUD_SinusReader.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SinusReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SinusReader.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_SinusReader::AUD_SinusReader(float frequency, AUD_SampleRate sampleRate) :
- m_frequency(frequency),
- m_position(0),
- m_sampleRate(sampleRate)
-{
-}
-
-bool AUD_SinusReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SinusReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_SinusReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SinusReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SinusReader::getSpecs() const
-{
- AUD_Specs specs;
- specs.rate = m_sampleRate;
- specs.channels = AUD_CHANNELS_MONO;
- return specs;
-}
-
-void AUD_SinusReader::read(int& length, bool& eos, sample_t* buffer)
-{
- // fill with sine data
- for(int i = 0; i < length; i++)
- {
- buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
- }
-
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SinusReader.h b/intern/audaspace/intern/AUD_SinusReader.h
deleted file mode 100644
index 50487ea94aa..00000000000
--- a/intern/audaspace/intern/AUD_SinusReader.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SinusReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SINUSREADER_H__
-#define __AUD_SINUSREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class is used for sine tone playback.
- * The sample rate can be specified, the signal is mono.
- */
-class AUD_SinusReader : public AUD_IReader
-{
-private:
- /**
- * The frequency of the sine wave.
- */
- const float m_frequency;
-
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The sample rate for the output.
- */
- const AUD_SampleRate m_sampleRate;
-
- // hide copy constructor and operator=
- AUD_SinusReader(const AUD_SinusReader&);
- AUD_SinusReader& operator=(const AUD_SinusReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param frequency The frequency of the sine wave.
- * \param sampleRate The output sample rate.
- */
- AUD_SinusReader(float frequency, AUD_SampleRate sampleRate);
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SINUSREADER_H__
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
deleted file mode 100644
index f9d65aa2363..00000000000
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_SoftwareDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SoftwareDevice.h"
-#include "AUD_IReader.h"
-#include "AUD_Mixer.h"
-#include "AUD_IFactory.h"
-#include "AUD_JOSResampleReader.h"
-#include "AUD_LinearResampleReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <cmath>
-#include <limits>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-typedef enum
-{
- AUD_RENDER_DISTANCE = 0x01,
- AUD_RENDER_DOPPLER = 0x02,
- AUD_RENDER_CONE = 0x04,
- AUD_RENDER_VOLUME = 0x08
-} AUD_RenderFlags;
-
-#define AUD_PITCH_MAX 10
-
-/******************************************************************************/
-/********************** AUD_SoftwareHandle Handle Code ************************/
-/******************************************************************************/
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PLAYING)
- {
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_SoftwareHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
- m_device->m_pausedSounds.push_back(This);
-
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
-
- m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
-
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
- m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_old_volume(1.0f), m_loopcount(0),
- m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
- m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
- m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
-{
-}
-
-void AUD_SoftwareDevice::AUD_SoftwareHandle::update()
-{
- int flags = 0;
-
- m_old_volume = m_volume;
-
- AUD_Vector3 SL;
- if(m_relative)
- SL = -m_location;
- else
- SL = m_device->m_location - m_location;
- float distance = SL * SL;
-
- if(distance > 0)
- distance = sqrt(distance);
- else
- flags |= AUD_RENDER_DOPPLER | AUD_RENDER_DISTANCE;
-
- if(m_pitch->getSpecs().channels != AUD_CHANNELS_MONO)
- {
- m_volume = m_user_volume;
- m_pitch->setPitch(m_user_pitch);
- return;
- }
-
- flags = ~(flags | m_flags | m_device->m_flags);
-
- // Doppler and Pitch
-
- if(flags & AUD_RENDER_DOPPLER)
- {
- float vls;
- if(m_relative)
- vls = 0;
- else
- vls = SL * m_device->m_velocity / distance;
- float vss = SL * m_velocity / distance;
- float max = m_device->m_speed_of_sound / m_device->m_doppler_factor;
- if(vss >= max)
- {
- m_pitch->setPitch(AUD_PITCH_MAX);
- }
- else
- {
- if(vls > max)
- vls = max;
-
- m_pitch->setPitch((m_device->m_speed_of_sound - m_device->m_doppler_factor * vls) / (m_device->m_speed_of_sound - m_device->m_doppler_factor * vss) * m_user_pitch);
- }
- }
- else
- m_pitch->setPitch(m_user_pitch);
-
- if(flags & AUD_RENDER_VOLUME)
- {
- // Distance
-
- if(flags & AUD_RENDER_DISTANCE)
- {
- if(m_device->m_distance_model == AUD_DISTANCE_MODEL_INVERSE_CLAMPED ||
- m_device->m_distance_model == AUD_DISTANCE_MODEL_LINEAR_CLAMPED ||
- m_device->m_distance_model == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
- {
- distance = AUD_MAX(AUD_MIN(m_distance_max, distance), m_distance_reference);
- }
-
- switch(m_device->m_distance_model)
- {
- case AUD_DISTANCE_MODEL_INVERSE:
- case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
- m_volume = m_distance_reference / (m_distance_reference + m_attenuation * (distance - m_distance_reference));
- break;
- case AUD_DISTANCE_MODEL_LINEAR:
- case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
- {
- float temp = m_distance_max - m_distance_reference;
- if(temp == 0)
- {
- if(distance > m_distance_reference)
- m_volume = 0.0f;
- else
- m_volume = 1.0f;
- }
- else
- m_volume = 1.0f - m_attenuation * (distance - m_distance_reference) / (m_distance_max - m_distance_reference);
- break;
- }
- case AUD_DISTANCE_MODEL_EXPONENT:
- case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
- if(m_distance_reference == 0)
- m_volume = 0;
- else
- m_volume = pow(distance / m_distance_reference, -m_attenuation);
- break;
- default:
- m_volume = 1.0f;
- }
- }
- else
- m_volume = 1.0f;
-
- // Cone
-
- if(flags & AUD_RENDER_CONE)
- {
- AUD_Vector3 SZ = m_orientation.getLookAt();
-
- float phi = acos(float(SZ * SL / (SZ.length() * SL.length())));
- float t = (phi - m_cone_angle_inner)/(m_cone_angle_outer - m_cone_angle_inner);
-
- if(t > 0)
- {
- if(t > 1)
- m_volume *= m_cone_volume_outer;
- else
- m_volume *= 1 + t * (m_cone_volume_outer - 1);
- }
- }
-
- if(m_volume > m_volume_max)
- m_volume = m_volume_max;
- else if(m_volume < m_volume_min)
- m_volume = m_volume_min;
-
- // Volume
-
- m_volume *= m_user_volume;
- }
-
- // 3D Cue
-
- AUD_Quaternion orientation;
-
- if(!m_relative)
- orientation = m_device->m_orientation;
-
- AUD_Vector3 Z = orientation.getLookAt();
- AUD_Vector3 N = orientation.getUp();
- AUD_Vector3 A = N * ((SL * N) / (N * N)) - SL;
-
- float Asquare = A * A;
-
- if(Asquare > 0)
- {
- float phi = acos(float(Z * A / (Z.length() * sqrt(Asquare))));
- if(N.cross(Z) * A > 0)
- phi = -phi;
-
- m_mapper->setMonoAngle(phi);
- }
- else
- m_mapper->setMonoAngle(m_relative ? m_user_pan * M_PI / 2.0 : 0);
-}
-
-void AUD_SoftwareDevice::AUD_SoftwareHandle::setSpecs(AUD_Specs specs)
-{
- m_mapper->setChannels(specs.channels);
- m_resampler->setRate(specs.rate);
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
-{
- return pause(false);
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PAUSED)
- {
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_SoftwareHandle> This = *it;
-
- m_device->m_pausedSounds.erase(it);
-
- m_device->m_playingSounds.push_back(This);
-
- if(!m_device->m_playback)
- m_device->playing(m_device->m_playback = true);
- m_status = AUD_STATUS_PLAYING;
-
- return true;
- }
- }
- }
-
- }
-
- return false;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_status = AUD_STATUS_INVALID;
-
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_SoftwareHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
-
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
-
- return true;
- }
- }
-
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- m_device->m_pausedSounds.erase(it);
- return true;
- }
- }
-
- return false;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep()
-{
- if(m_status)
- return m_keep;
-
- return false;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_keep = keep;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_pitch->setPitch(m_user_pitch);
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
-
- if(m_status == AUD_STATUS_STOPPED)
- m_status = AUD_STATUS_PAUSED;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return 0.0f;
-
- float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
-
- return position;
-}
-
-AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus()
-{
- return m_status;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume()
-{
- return m_user_volume;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
-{
- if(!m_status)
- return false;
- m_user_volume = volume;
-
- if(volume == 0)
- {
- m_old_volume = m_volume = volume;
- m_flags |= AUD_RENDER_VOLUME;
- }
- else
- m_flags &= ~AUD_RENDER_VOLUME;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch()
-{
- return m_user_pitch;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch)
-{
- if(!m_status)
- return false;
- if(pitch <= 0)
- pitch = 1;
- m_user_pitch = pitch;
- return true;
-}
-
-int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount()
-{
- if(!m_status)
- return 0;
- return m_loopcount;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
-{
- if(!m_status)
- return false;
-
- if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
- m_status = AUD_STATUS_PAUSED;
-
- m_loopcount = count;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_stop = callback;
- m_stop_data = data;
-
- return true;
-}
-
-
-
-/******************************************************************************/
-/******************** AUD_SoftwareHandle 3DHandle Code ************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceLocation()
-{
- if(!m_status)
- return AUD_Vector3();
-
- return m_location;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceLocation(const AUD_Vector3& location)
-{
- if(!m_status)
- return false;
-
- m_location = location;
-
- return true;
-}
-
-AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceVelocity()
-{
- if(!m_status)
- return AUD_Vector3();
-
- return m_velocity;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceVelocity(const AUD_Vector3& velocity)
-{
- if(!m_status)
- return false;
-
- m_velocity = velocity;
-
- return true;
-}
-
-AUD_Quaternion AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceOrientation()
-{
- if(!m_status)
- return AUD_Quaternion();
-
- return m_orientation;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceOrientation(const AUD_Quaternion& orientation)
-{
- if(!m_status)
- return false;
-
- m_orientation = orientation;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::isRelative()
-{
- if(!m_status)
- return false;
-
- return m_relative;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setRelative(bool relative)
-{
- if(!m_status)
- return false;
-
- m_relative = relative;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMaximum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_volume_max;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMaximum(float volume)
-{
- if(!m_status)
- return false;
-
- m_volume_max = volume;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMinimum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_volume_min;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMinimum(float volume)
-{
- if(!m_status)
- return false;
-
- m_volume_min = volume;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceMaximum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_distance_max;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceMaximum(float distance)
-{
- if(!m_status)
- return false;
-
- m_distance_max = distance;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceReference()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_distance_reference;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceReference(float distance)
-{
- if(!m_status)
- return false;
-
- m_distance_reference = distance;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getAttenuation()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_attenuation;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setAttenuation(float factor)
-{
- if(!m_status)
- return false;
-
- m_attenuation = factor;
-
- if(factor == 0)
- m_flags |= AUD_RENDER_DISTANCE;
- else
- m_flags &= ~AUD_RENDER_DISTANCE;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleOuter()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_angle_outer * 360.0f / M_PI;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleOuter(float angle)
-{
- if(!m_status)
- return false;
-
- m_cone_angle_outer = angle * M_PI / 360.0f;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleInner()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_angle_inner * 360.0f / M_PI;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleInner(float angle)
-{
- if(!m_status)
- return false;
-
- if(angle >= 360)
- m_flags |= AUD_RENDER_CONE;
- else
- m_flags &= ~AUD_RENDER_CONE;
-
- m_cone_angle_inner = angle * M_PI / 360.0f;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeVolumeOuter()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_volume_outer;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeVolumeOuter(float volume)
-{
- if(!m_status)
- return false;
-
- m_cone_volume_outer = volume;
-
- return true;
-}
-
-/******************************************************************************/
-/**************************** IDevice Code ************************************/
-/******************************************************************************/
-
-void AUD_SoftwareDevice::create()
-{
- m_playback = false;
- m_volume = 1.0f;
- m_mixer = boost::shared_ptr<AUD_Mixer>(new AUD_Mixer(m_specs));
- m_speed_of_sound = 343.3f;
- m_doppler_factor = 1.0f;
- m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
- m_flags = 0;
- m_quality = false;
-
- 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);
-}
-
-void AUD_SoftwareDevice::destroy()
-{
- if(m_playback)
- playing(m_playback = false);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_SoftwareDevice::mix(data_t* buffer, int length)
-{
- m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
-
- AUD_MutexLock lock(*this);
-
- {
- boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
- int len;
- int pos;
- bool eos;
- std::list<boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
- std::list<boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> > pauseSounds;
- sample_t* buf = m_buffer.getBuffer();
-
- m_mixer->clear(length);
-
- // for all sounds
- AUD_HandleIterator it = m_playingSounds.begin();
- while(it != m_playingSounds.end())
- {
- sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
-
- // get the buffer from the source
- pos = 0;
- len = length;
-
- // update 3D Info
- sound->update();
-
- sound->m_reader->read(len, eos, buf);
-
- // in case of looping
- while(pos + len < length && sound->m_loopcount && eos)
- {
- m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
-
- pos += len;
-
- if(sound->m_loopcount > 0)
- sound->m_loopcount--;
-
- sound->m_reader->seek(0);
-
- len = length - pos;
- sound->m_reader->read(len, eos, buf);
-
- // prevent endless loop
- if(!len)
- break;
- }
-
- m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
-
- // in case the end of the sound is reached
- if(eos && !sound->m_loopcount)
- {
- if(sound->m_stop)
- sound->m_stop(sound->m_stop_data);
-
- if(sound->m_keep)
- pauseSounds.push_back(sound);
- else
- stopSounds.push_back(sound);
- }
- }
-
- // superpose
- m_mixer->read(buffer, m_volume);
-
- // cleanup
- for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- (*it)->pause(true);
-
- for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- (*it)->stop();
-
- pauseSounds.clear();
- stopSounds.clear();
- }
-}
-
-void AUD_SoftwareDevice::setPanning(AUD_IHandle* handle, float pan)
-{
- AUD_SoftwareDevice::AUD_SoftwareHandle* h = dynamic_cast<AUD_SoftwareDevice::AUD_SoftwareHandle*>(handle);
- h->m_user_pan = pan;
-}
-
-void AUD_SoftwareDevice::setQuality(bool quality)
-{
- m_quality = quality;
-}
-
-void AUD_SoftwareDevice::setSpecs(AUD_Specs specs)
-{
- m_specs.specs = specs;
- m_mixer->setSpecs(specs);
-
- for(AUD_HandleIterator it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
- {
- (*it)->setSpecs(specs);
- }
-}
-
-AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
-{
- return m_specs;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_SoftwareDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- // prepare the reader
- // pitch
-
- boost::shared_ptr<AUD_PitchReader> pitch = boost::shared_ptr<AUD_PitchReader>(new AUD_PitchReader(reader, 1));
- reader = boost::shared_ptr<AUD_IReader>(pitch);
-
- boost::shared_ptr<AUD_ResampleReader> resampler;
-
- // resample
- if(m_quality)
- resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_JOSResampleReader(reader, m_specs.specs));
- else
- resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_LinearResampleReader(reader, m_specs.specs));
- reader = boost::shared_ptr<AUD_IReader>(resampler);
-
- // rechannel
- boost::shared_ptr<AUD_ChannelMapperReader> mapper = boost::shared_ptr<AUD_ChannelMapperReader>(new AUD_ChannelMapperReader(reader, m_specs.channels));
- reader = boost::shared_ptr<AUD_IReader>(mapper);
-
- if(!reader.get())
- return boost::shared_ptr<AUD_IHandle>();
-
- // play sound
- boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle>(new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
-
- AUD_MutexLock lock(*this);
-
- m_playingSounds.push_back(sound);
-
- if(!m_playback)
- playing(m_playback = true);
-
- return boost::shared_ptr<AUD_IHandle>(sound);
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_SoftwareDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- return play(factory->createReader(), keep);
-}
-
-void AUD_SoftwareDevice::stopAll()
-{
- AUD_MutexLock lock(*this);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-}
-
-void AUD_SoftwareDevice::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SoftwareDevice::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-float AUD_SoftwareDevice::getVolume() const
-{
- return m_volume;
-}
-
-void AUD_SoftwareDevice::setVolume(float volume)
-{
- m_volume = volume;
-}
-
-/******************************************************************************/
-/**************************** 3D Device Code **********************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_SoftwareDevice::getListenerLocation() const
-{
- return m_location;
-}
-
-void AUD_SoftwareDevice::setListenerLocation(const AUD_Vector3& location)
-{
- m_location = location;
-}
-
-AUD_Vector3 AUD_SoftwareDevice::getListenerVelocity() const
-{
- return m_velocity;
-}
-
-void AUD_SoftwareDevice::setListenerVelocity(const AUD_Vector3& velocity)
-{
- m_velocity = velocity;
-}
-
-AUD_Quaternion AUD_SoftwareDevice::getListenerOrientation() const
-{
- return m_orientation;
-}
-
-void AUD_SoftwareDevice::setListenerOrientation(const AUD_Quaternion& orientation)
-{
- m_orientation = orientation;
-}
-
-float AUD_SoftwareDevice::getSpeedOfSound() const
-{
- return m_speed_of_sound;
-}
-
-void AUD_SoftwareDevice::setSpeedOfSound(float speed)
-{
- m_speed_of_sound = speed;
-}
-
-float AUD_SoftwareDevice::getDopplerFactor() const
-{
- return m_doppler_factor;
-}
-
-void AUD_SoftwareDevice::setDopplerFactor(float factor)
-{
- m_doppler_factor = factor;
- if(factor == 0)
- m_flags |= AUD_RENDER_DOPPLER;
- else
- m_flags &= ~AUD_RENDER_DOPPLER;
-}
-
-AUD_DistanceModel AUD_SoftwareDevice::getDistanceModel() const
-{
- return m_distance_model;
-}
-
-void AUD_SoftwareDevice::setDistanceModel(AUD_DistanceModel model)
-{
- m_distance_model = model;
- if(model == AUD_DISTANCE_MODEL_INVALID)
- m_flags |= AUD_RENDER_DISTANCE;
- else
- m_flags &= ~AUD_RENDER_DISTANCE;
-}
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
deleted file mode 100644
index 26bbdc5a8f7..00000000000
--- a/intern/audaspace/intern/AUD_Space.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Space.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SPACE_H__
-#define __AUD_SPACE_H__
-
-/// The size of a format in bytes.
-#define AUD_FORMAT_SIZE(format) (format & 0x0F)
-/// The size of a sample in the specified device format in bytes.
-#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
-/// The size of a sample in the specified format in bytes.
-#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
-/// Throws a AUD_Exception with the provided error code.
-#define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; }
-
-/// Compares two audio data specifications.
-#define AUD_COMPARE_SPECS(s1, s2) ((s1.rate == s2.rate) && (s1.channels == s2.channels))
-
-/// Returns the bit for a channel mask.
-#define AUD_CHANNEL_BIT(channel) (0x01 << channel)
-
-/// Returns the smaller of the two values.
-#define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b))
-/// Returns the bigger of the two values.
-#define AUD_MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-// 5 sec * 48000 samples/sec * 4 bytes/sample * 6 channels
-/// The size by which a buffer should be resized if the final extent is unknown.
-#define AUD_BUFFER_RESIZE_BYTES 5760000
-
-/// The default playback buffer size of a device.
-#define AUD_DEFAULT_BUFFER_SIZE 1024
-
-/**
- * The format of a sample.
- * The last 4 bit save the byte count of the format.
- */
-typedef enum
-{
- AUD_FORMAT_INVALID = 0x00, /// Invalid sample format.
- AUD_FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
- AUD_FORMAT_S16 = 0x12, /// 2 byte signed integer.
- AUD_FORMAT_S24 = 0x13, /// 3 byte signed integer.
- AUD_FORMAT_S32 = 0x14, /// 4 byte signed integer.
- AUD_FORMAT_FLOAT32 = 0x24, /// 4 byte float.
- AUD_FORMAT_FLOAT64 = 0x28 /// 8 byte float.
-} AUD_SampleFormat;
-
-/// The channel count.
-typedef enum
-{
- AUD_CHANNELS_INVALID = 0, /// Invalid channel count.
- AUD_CHANNELS_MONO = 1, /// Mono.
- AUD_CHANNELS_STEREO = 2, /// Stereo.
- AUD_CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
- AUD_CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
- AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
- AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
- AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
- AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
-} AUD_Channels;
-
-/// The channel names.
-typedef enum
-{
- AUD_CHANNEL_FRONT_LEFT = 0,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT,
- AUD_CHANNEL_REAR_CENTER,
- AUD_CHANNEL_SIDE_LEFT,
- AUD_CHANNEL_SIDE_RIGHT,
- AUD_CHANNEL_MAX
-} AUD_Channel;
-
-/**
- * The sample rate tells how many samples are played back within one second.
- * Some exotic formats may use other sample rates than provided here.
- */
-typedef enum
-{
- AUD_RATE_INVALID = 0, /// Invalid sample rate.
- AUD_RATE_8000 = 8000, /// 8000 Hz.
- AUD_RATE_16000 = 16000, /// 16000 Hz.
- AUD_RATE_11025 = 11025, /// 11025 Hz.
- AUD_RATE_22050 = 22050, /// 22050 Hz.
- AUD_RATE_32000 = 32000, /// 32000 Hz.
- AUD_RATE_44100 = 44100, /// 44100 Hz.
- AUD_RATE_48000 = 48000, /// 48000 Hz.
- AUD_RATE_88200 = 88200, /// 88200 Hz.
- AUD_RATE_96000 = 96000, /// 96000 Hz.
- AUD_RATE_192000 = 192000 /// 192000 Hz.
-} AUD_DefaultSampleRate;
-
-/// Status of a playback handle.
-typedef enum
-{
- AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
- AUD_STATUS_PLAYING, /// Sound is playing.
- AUD_STATUS_PAUSED, /// Sound is being paused.
- AUD_STATUS_STOPPED /// Sound is stopped but kept in the device.
-} AUD_Status;
-
-/// Error codes for exceptions (C++ library) or for return values (C API).
-typedef enum
-{
- AUD_NO_ERROR = 0,
- AUD_ERROR_SPECS,
- AUD_ERROR_PROPS,
- AUD_ERROR_FILE,
- AUD_ERROR_SRC,
- AUD_ERROR_FFMPEG,
- AUD_ERROR_OPENAL,
- AUD_ERROR_SDL,
- AUD_ERROR_JACK
-} AUD_Error;
-
-/// Fading types.
-typedef enum
-{
- AUD_FADE_IN,
- AUD_FADE_OUT
-} AUD_FadeType;
-
-/// Possible distance models for the 3D device.
-typedef enum
-{
- AUD_DISTANCE_MODEL_INVALID = 0,
- AUD_DISTANCE_MODEL_INVERSE,
- AUD_DISTANCE_MODEL_INVERSE_CLAMPED,
- AUD_DISTANCE_MODEL_LINEAR,
- AUD_DISTANCE_MODEL_LINEAR_CLAMPED,
- AUD_DISTANCE_MODEL_EXPONENT,
- AUD_DISTANCE_MODEL_EXPONENT_CLAMPED
-} AUD_DistanceModel;
-
-/// Possible animatable properties for Sequencer Factories and Entries.
-typedef enum
-{
- AUD_AP_VOLUME,
- AUD_AP_PANNING,
- AUD_AP_PITCH,
- AUD_AP_LOCATION,
- AUD_AP_ORIENTATION
-} AUD_AnimateablePropertyType;
-
-/// Container formats for writers.
-typedef enum
-{
- AUD_CONTAINER_INVALID = 0,
- AUD_CONTAINER_AC3,
- AUD_CONTAINER_FLAC,
- AUD_CONTAINER_MATROSKA,
- AUD_CONTAINER_MP2,
- AUD_CONTAINER_MP3,
- AUD_CONTAINER_OGG,
- AUD_CONTAINER_WAV
-} AUD_Container;
-
-/// Audio codecs for writers.
-typedef enum
-{
- AUD_CODEC_INVALID = 0,
- AUD_CODEC_AAC,
- AUD_CODEC_AC3,
- AUD_CODEC_FLAC,
- AUD_CODEC_MP2,
- AUD_CODEC_MP3,
- AUD_CODEC_PCM,
- AUD_CODEC_VORBIS
-} AUD_Codec;
-
-/// Sample type.(float samples)
-typedef float sample_t;
-
-/// Sample data type (format samples)
-typedef unsigned char data_t;
-
-/// Sample rate type.
-typedef double AUD_SampleRate;
-
-/// Specification of a sound source.
-typedef struct
-{
- /// Sample rate in Hz.
- AUD_SampleRate rate;
-
- /// Channel count.
- AUD_Channels channels;
-} AUD_Specs;
-
-/// Specification of a sound device.
-typedef struct
-{
- /// Sample format.
- AUD_SampleFormat format;
-
- union
- {
- struct
- {
- /// Sample rate in Hz.
- AUD_SampleRate rate;
-
- /// Channel count.
- AUD_Channels channels;
- };
- AUD_Specs specs;
- };
-} AUD_DeviceSpecs;
-
-/// Exception structure.
-typedef struct
-{
- /**
- * Error code.
- * \see AUD_Error
- */
- AUD_Error error;
-
- /**
- * Error string.
- */
- const char* str;
-
- // void* userData; - for the case it is needed someday
-} AUD_Exception;
-
-#endif //__AUD_SPACE_H__
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
deleted file mode 100644
index daa714aeec3..00000000000
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_StreamBufferFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_StreamBufferFactory.h"
-#include "AUD_BufferReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-AUD_StreamBufferFactory::AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory) :
- m_buffer(new AUD_Buffer())
-{
- boost::shared_ptr<AUD_IReader> reader = factory->createReader();
-
- m_specs = reader->getSpecs();
-
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
- int length;
- int index = 0;
- bool eos = false;
-
- // get an approximated size if possible
- int size = reader->getLength();
-
- if(size <= 0)
- size = AUD_BUFFER_RESIZE_BYTES / sample_size;
- else
- size += m_specs.rate;
-
- // as long as the end of the stream is not reached
- while(!eos)
- {
- // increase
- m_buffer->resize(size*sample_size, true);
-
- // read more
- length = size-index;
- reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels);
- if(index == m_buffer->getSize() / sample_size)
- size += AUD_BUFFER_RESIZE_BYTES / sample_size;
- index += length;
- }
-
- m_buffer->resize(index * sample_size, true);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_StreamBufferFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_BufferReader(m_buffer, m_specs));
-}
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.h b/intern/audaspace/intern/AUD_StreamBufferFactory.h
deleted file mode 100644
index 1bcd73d59b6..00000000000
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_StreamBufferFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_STREAMBUFFERFACTORY_H__
-#define __AUD_STREAMBUFFERFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory creates a buffer out of a reader. This way normally streamed
- * sound sources can be loaded into memory for buffered playback.
- */
-class AUD_StreamBufferFactory : public AUD_IFactory
-{
-private:
- /**
- * The buffer that holds the audio data.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- /**
- * The specification of the samples.
- */
- AUD_Specs m_specs;
-
- // hide copy constructor and operator=
- AUD_StreamBufferFactory(const AUD_StreamBufferFactory&);
- AUD_StreamBufferFactory& operator=(const AUD_StreamBufferFactory&);
-
-public:
- /**
- * Creates the factory and reads the reader created by the factory supplied
- * to the buffer.
- * \param factory The factory that creates the reader for buffering.
- * \exception AUD_Exception Thrown if the reader cannot be created.
- */
- AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_STREAMBUFFERFACTORY_H__
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
deleted file mode 100644
index cfbf80ac110..00000000000
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/jack/AUD_JackDevice.cpp
- * \ingroup audjack
- */
-
-#include "AUD_JackDevice.h"
-#include "AUD_IReader.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-void* AUD_JackDevice::runMixingThread(void* device)
-{
- ((AUD_JackDevice*)device)->updateRingBuffers();
- return NULL;
-}
-
-void AUD_JackDevice::updateRingBuffers()
-{
- size_t size, temp;
- unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
- unsigned int i, j;
- unsigned int channels = m_specs.channels;
- sample_t* buffer = m_buffer.getBuffer();
- float* deinterleave = m_deinterleavebuf.getBuffer();
- jack_transport_state_t state;
- jack_position_t position;
-
- pthread_mutex_lock(&m_mixingLock);
- while(m_valid)
- {
- if(m_sync > 1)
- {
- if(m_syncFunc)
- {
- state = AUD_jack_transport_query(m_client, &position);
- m_syncFunc(m_syncFuncData, state != JackTransportStopped, position.frame / (float) m_specs.rate);
- }
-
- for(i = 0; i < channels; i++)
- AUD_jack_ringbuffer_reset(m_ringbuffers[i]);
- }
-
- size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
- for(i = 1; i < channels; i++)
- if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
- size = temp;
-
- while(size > samplesize)
- {
- size /= samplesize;
- mix((data_t*)buffer, size);
- for(i = 0; i < channels; i++)
- {
- for(j = 0; j < size; j++)
- deinterleave[i * size + j] = buffer[i + j * channels];
- AUD_jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
- }
-
- size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
- for(i = 1; i < channels; i++)
- if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
- size = temp;
- }
-
- if(m_sync > 1)
- {
- m_sync = 3;
- }
-
- pthread_cond_wait(&m_mixingCondition, &m_mixingLock);
- }
- pthread_mutex_unlock(&m_mixingLock);
-}
-
-int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
- unsigned int i;
- int count = device->m_specs.channels;
- char* buffer;
-
- if(device->m_sync)
- {
- // play silence while syncing
- for(unsigned int i = 0; i < count; i++)
- memset(AUD_jack_port_get_buffer(device->m_ports[i], length), 0, length * sizeof(float));
- }
- else
- {
- size_t temp;
- size_t readsamples = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[0]);
- for(i = 1; i < count; i++)
- if((temp = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
- readsamples = temp;
-
- readsamples = AUD_MIN(readsamples / sizeof(float), length);
-
- for(unsigned int i = 0; i < count; i++)
- {
- buffer = (char*)AUD_jack_port_get_buffer(device->m_ports[i], length);
- AUD_jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
- if(readsamples < length)
- memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
- }
-
- if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
- {
- pthread_cond_signal(&(device->m_mixingCondition));
- pthread_mutex_unlock(&(device->m_mixingLock));
- }
- }
-
- return 0;
-}
-
-int AUD_JackDevice::jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
-
- if(state == JackTransportStopped)
- return 1;
-
- if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
- {
- if(device->m_sync > 2)
- {
- if(device->m_sync == 3)
- {
- device->m_sync = 0;
- pthread_mutex_unlock(&(device->m_mixingLock));
- return 1;
- }
- }
- else
- {
- device->m_sync = 2;
- pthread_cond_signal(&(device->m_mixingCondition));
- }
- pthread_mutex_unlock(&(device->m_mixingLock));
- }
- else if(!device->m_sync)
- device->m_sync = 1;
-
- return 0;
-}
-
-void AUD_JackDevice::jack_shutdown(void *data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
- device->m_valid = false;
-}
-
-static const char* clientopen_error = "AUD_JackDevice: Couldn't connect to "
- "jack server.";
-static const char* port_error = "AUD_JackDevice: Couldn't create output port.";
-static const char* activate_error = "AUD_JackDevice: Couldn't activate the "
- "client.";
-
-AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize)
-{
- if(specs.channels == AUD_CHANNELS_INVALID)
- specs.channels = AUD_CHANNELS_STEREO;
-
- // jack uses floats
- m_specs = specs;
- m_specs.format = AUD_FORMAT_FLOAT32;
-
- jack_options_t options = JackNullOption;
- jack_status_t status;
-
- // open client
- m_client = AUD_jack_client_open(name.c_str(), options, &status);
- if(m_client == NULL)
- AUD_THROW(AUD_ERROR_JACK, clientopen_error);
-
- // set callbacks
- AUD_jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
- AUD_jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
- AUD_jack_set_sync_callback(m_client, AUD_JackDevice::jack_sync, this);
-
- // register our output channels which are called ports in jack
- m_ports = new jack_port_t*[m_specs.channels];
-
- try
- {
- char portname[64];
- for(int i = 0; i < m_specs.channels; i++)
- {
- sprintf(portname, "out %d", i+1);
- m_ports[i] = AUD_jack_port_register(m_client, portname,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- if(m_ports[i] == NULL)
- AUD_THROW(AUD_ERROR_JACK, port_error);
- }
- }
- catch(AUD_Exception&)
- {
- AUD_jack_client_close(m_client);
- delete[] m_ports;
- throw;
- }
-
- m_specs.rate = (AUD_SampleRate)AUD_jack_get_sample_rate(m_client);
-
- buffersize *= sizeof(sample_t);
- m_ringbuffers = new jack_ringbuffer_t*[specs.channels];
- for(unsigned int i = 0; i < specs.channels; i++)
- m_ringbuffers[i] = AUD_jack_ringbuffer_create(buffersize);
- buffersize *= specs.channels;
- m_deinterleavebuf.resize(buffersize);
- m_buffer.resize(buffersize);
-
- create();
-
- m_valid = true;
- m_sync = 0;
- m_syncFunc = NULL;
- m_nextState = m_state = AUD_jack_transport_query(m_client, NULL);
-
- pthread_mutex_init(&m_mixingLock, NULL);
- pthread_cond_init(&m_mixingCondition, NULL);
-
- // activate the client
- if(AUD_jack_activate(m_client))
- {
- AUD_jack_client_close(m_client);
- delete[] m_ports;
- for(unsigned int i = 0; i < specs.channels; i++)
- AUD_jack_ringbuffer_free(m_ringbuffers[i]);
- delete[] m_ringbuffers;
- pthread_mutex_destroy(&m_mixingLock);
- pthread_cond_destroy(&m_mixingCondition);
- destroy();
-
- AUD_THROW(AUD_ERROR_JACK, activate_error);
- }
-
- const char** ports = AUD_jack_get_ports(m_client, NULL, NULL,
- JackPortIsPhysical | JackPortIsInput);
- if(ports != NULL)
- {
- for(int i = 0; i < m_specs.channels && ports[i]; i++)
- AUD_jack_connect(m_client, AUD_jack_port_name(m_ports[i]), ports[i]);
-
- free(ports);
- }
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&m_mixingThread, &attr, runMixingThread, this);
-
- pthread_attr_destroy(&attr);
-}
-
-AUD_JackDevice::~AUD_JackDevice()
-{
- if(m_valid)
- AUD_jack_client_close(m_client);
- m_valid = false;
-
- delete[] m_ports;
-
- pthread_mutex_lock(&m_mixingLock);
- pthread_cond_signal(&m_mixingCondition);
- pthread_mutex_unlock(&m_mixingLock);
- pthread_join(m_mixingThread, NULL);
-
- pthread_cond_destroy(&m_mixingCondition);
- pthread_mutex_destroy(&m_mixingLock);
- for(unsigned int i = 0; i < m_specs.channels; i++)
- AUD_jack_ringbuffer_free(m_ringbuffers[i]);
- delete[] m_ringbuffers;
-
- destroy();
-}
-
-void AUD_JackDevice::playing(bool playing)
-{
- // Do nothing.
-}
-
-void AUD_JackDevice::startPlayback()
-{
- AUD_jack_transport_start(m_client);
- m_nextState = JackTransportRolling;
-}
-
-void AUD_JackDevice::stopPlayback()
-{
- AUD_jack_transport_stop(m_client);
- m_nextState = JackTransportStopped;
-}
-
-void AUD_JackDevice::seekPlayback(float time)
-{
- if(time >= 0.0f)
- AUD_jack_transport_locate(m_client, time * m_specs.rate);
-}
-
-void AUD_JackDevice::setSyncCallback(AUD_syncFunction sync, void* data)
-{
- m_syncFunc = sync;
- m_syncFuncData = data;
-}
-
-float AUD_JackDevice::getPlaybackPosition()
-{
- jack_position_t position;
- AUD_jack_transport_query(m_client, &position);
- return position.frame / (float) m_specs.rate;
-}
-
-bool AUD_JackDevice::doesPlayback()
-{
- jack_transport_state_t state = AUD_jack_transport_query(m_client, NULL);
-
- if(state != m_state)
- m_nextState = m_state = state;
-
- return m_nextState != JackTransportStopped;
-}
diff --git a/intern/audaspace/jack/AUD_JackLibrary.cpp b/intern/audaspace/jack/AUD_JackLibrary.cpp
deleted file mode 100644
index 9ed6862bbb9..00000000000
--- a/intern/audaspace/jack/AUD_JackLibrary.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2013 Blender Foundation
- *
- * This file is part of AudaSpace.
- *
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/jack/AUD_JackLibrary.cpp
- * \ingroup audjack
- */
-
-#define AUD_JACK_LIBRARY_IMPL
-
-#include "AUD_JackLibrary.h"
-
-#ifdef WITH_JACK_DYNLOAD
-# include <dlfcn.h>
-# include <stdio.h>
-#endif
-
-#ifdef WITH_JACK_DYNLOAD
-static void *jack_handle = NULL;
-#endif
-
-static bool jack_supported = false;
-
-void AUD_jack_init(void)
-{
-#ifdef WITH_JACK_DYNLOAD
- const char *names[] = {"libjack.so",
- "libjack.so.0",
- "libjack.so.1",
- "libjack.so.2",
- NULL};
- int index = 0;
- while (names[index] != NULL) {
- jack_handle = dlopen(names[index], RTLD_LAZY);
- if (jack_handle != NULL) {
- // Found existing library.
- break;
- }
- ++index;
- }
-
- if (!jack_handle) {
- return;
- }
-
-# define JACK_SYMBOL(sym) \
- { \
- char *error; \
- *(void **) (&(AUD_##sym)) = dlsym(jack_handle, #sym); \
- if ((error = dlerror()) != NULL) { \
- fprintf(stderr, "%s\n", error); \
- return; \
- } \
- } (void)0
-
- dlerror(); /* Clear any existing error */
-#else // WITH_JACK_DYNLOAD
-# define JACK_SYMBOL(sym) AUD_##sym = sym
-#endif // WITH_JACK_DYNLOAD
-
- JACK_SYMBOL(jack_transport_query);
- JACK_SYMBOL(jack_transport_locate);
-
- JACK_SYMBOL(jack_transport_start);
- JACK_SYMBOL(jack_transport_stop);
-
- JACK_SYMBOL(jack_ringbuffer_reset);
- JACK_SYMBOL(jack_ringbuffer_write);
- JACK_SYMBOL(jack_ringbuffer_write_space);
- JACK_SYMBOL(jack_ringbuffer_write_advance);
- JACK_SYMBOL(jack_ringbuffer_read);
- JACK_SYMBOL(jack_ringbuffer_create);
- JACK_SYMBOL(jack_ringbuffer_free);
- JACK_SYMBOL(jack_ringbuffer_read_space);
- JACK_SYMBOL(jack_set_sync_callback);
-
- JACK_SYMBOL(jack_port_get_buffer);
-
- JACK_SYMBOL(jack_client_open);
- JACK_SYMBOL(jack_set_process_callback);
- JACK_SYMBOL(jack_on_shutdown);
- JACK_SYMBOL(jack_port_register);
- JACK_SYMBOL(jack_client_close);
- JACK_SYMBOL(jack_get_sample_rate);
- JACK_SYMBOL(jack_activate);
- JACK_SYMBOL(jack_get_ports);
- JACK_SYMBOL(jack_port_name);
- JACK_SYMBOL(jack_connect);
-
- jack_supported = true;
-
-#undef JACK_SYMBOL
-}
-
-void AUD_jack_exit(void)
-{
-#ifdef WITH_JACK_DYNLOAD
- if (jack_handle) {
- dlclose(jack_handle);
- }
-#endif
- jack_supported = false;
-}
-
-bool AUD_jack_supported(void)
-{
- return jack_supported;
-}
diff --git a/intern/audaspace/jack/AUD_JackLibrary.h b/intern/audaspace/jack/AUD_JackLibrary.h
deleted file mode 100644
index d74d9ba8021..00000000000
--- a/intern/audaspace/jack/AUD_JackLibrary.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2013 Blender Foundation
- *
- * This file is part of AudaSpace.
- *
- * Audaspace 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.
- *
- * 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/jack/AUD_JackLibrary.cpp
- * \ingroup audjack
- */
-
-#ifndef __AUD_JACKLIBRARY__
-#define __AUD_JACKLIBRARY__
-
-#if defined(__APPLE__) // always first include for jack weaklinking !
-#include <weakjack.h>
-#endif
-
-#include <jack.h>
-#include <ringbuffer.h>
-
-#ifdef AUD_JACK_LIBRARY_IMPL
-# define JACK_SYM
-#else
-# define JACK_SYM extern
-#endif
-
-/* All loadable JACK sumbols, prototypes from original jack.h */
-
-JACK_SYM jack_transport_state_t (*AUD_jack_transport_query) (
- const jack_client_t *client,
- jack_position_t *pos);
-
-JACK_SYM int (*AUD_jack_transport_locate) (jack_client_t *client,
- jack_nframes_t frame);
-
-JACK_SYM void (*AUD_jack_transport_start) (jack_client_t *client);
-JACK_SYM void (*AUD_jack_transport_stop) (jack_client_t *client);
-
-JACK_SYM void (*AUD_jack_ringbuffer_reset) (jack_ringbuffer_t *rb);
-JACK_SYM size_t (*AUD_jack_ringbuffer_write) (jack_ringbuffer_t *rb,
- const char *src, size_t cnt);
-JACK_SYM size_t (*AUD_jack_ringbuffer_write_space) (const jack_ringbuffer_t *rb);
-JACK_SYM void (*AUD_jack_ringbuffer_write_advance) (jack_ringbuffer_t *rb,
- size_t cnt);
-JACK_SYM size_t (*AUD_jack_ringbuffer_read) (jack_ringbuffer_t *rb, char *dest,
- size_t cnt);
-JACK_SYM jack_ringbuffer_t *(*AUD_jack_ringbuffer_create) (size_t sz);
-JACK_SYM void (*AUD_jack_ringbuffer_free) (jack_ringbuffer_t *rb);
-JACK_SYM size_t (*AUD_jack_ringbuffer_read_space) (const jack_ringbuffer_t *rb);
-JACK_SYM int (*AUD_jack_set_sync_callback) (jack_client_t *client,
- JackSyncCallback sync_callback,
- void *arg);
-
-JACK_SYM void *(*AUD_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
-
-JACK_SYM jack_client_t *(*AUD_jack_client_open) (const char *client_name,
- jack_options_t options,
- jack_status_t *status, ...);
-JACK_SYM int (*AUD_jack_set_process_callback) (jack_client_t *client,
- JackProcessCallback process_callback, void *arg);
-JACK_SYM void (*AUD_jack_on_shutdown) (jack_client_t *client,
- JackShutdownCallback function, void *arg);
-JACK_SYM jack_port_t *(*AUD_jack_port_register) (jack_client_t *client,
- const char *port_name,
- const char *port_type,
- unsigned long flags,
- unsigned long buffer_size);
-JACK_SYM int (*AUD_jack_client_close) (jack_client_t *client);
-JACK_SYM jack_nframes_t (*AUD_jack_get_sample_rate) (jack_client_t *);
-JACK_SYM int (*AUD_jack_activate) (jack_client_t *client);
-JACK_SYM const char **(*AUD_jack_get_ports) (jack_client_t *,
- const char *port_name_pattern,
- const char *type_name_pattern,
- unsigned long flags);
-JACK_SYM const char *(*AUD_jack_port_name) (const jack_port_t *port);
-JACK_SYM int (*AUD_jack_connect) (jack_client_t *,
- const char *source_port,
- const char *destination_port);
-
-/* Public API */
-
-void AUD_jack_init(void);
-void AUD_jack_exit(void);
-bool AUD_jack_supported(void);
-
-#endif // __AUD_JACKLIBRARY__
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
deleted file mode 100644
index 106b2937a06..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileFactory.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileFactory.h"
-#include "AUD_SndFileReader.h"
-
-#include <cstring>
-
-AUD_SndFileFactory::AUD_SndFileFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_SndFileFactory::AUD_SndFileFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SndFileFactory::createReader()
-{
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_filename));
-}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
deleted file mode 100644
index bc96325d6eb..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileFactory.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEFACTORY_H__
-#define __AUD_SNDFILEFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory reads a sound file via libsndfile.
- */
-class AUD_SndFileFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_SndFileFactory(const AUD_SndFileFactory&);
- AUD_SndFileFactory& operator=(const AUD_SndFileFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_SndFileFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_SndFileFactory(const data_t* buffer, int size);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SNDFILEFACTORY_H__
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
deleted file mode 100644
index aaee814f56b..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileReader.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileReader.h"
-
-#include <cstring>
-
-sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
- return reader->m_membuffer->getSize();
-}
-
-sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
- void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- switch(whence)
- {
- case SEEK_SET:
- reader->m_memoffset = offset;
- break;
- case SEEK_CUR:
- reader->m_memoffset = reader->m_memoffset + offset;
- break;
- case SEEK_END:
- reader->m_memoffset = reader->m_membuffer->getSize() + offset;
- break;
- }
-
- return reader->m_memoffset;
-}
-
-sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
- void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- if(reader->m_memoffset + count > reader->m_membuffer->getSize())
- count = reader->m_membuffer->getSize() - reader->m_memoffset;
-
- memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
- reader->m_memoffset, count);
- reader->m_memoffset += count;
-
- return count;
-}
-
-sf_count_t AUD_SndFileReader::vio_tell(void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- return reader->m_memoffset;
-}
-
-static const char* fileopen_error = "AUD_SndFileReader: File couldn't be "
- "read.";
-
-AUD_SndFileReader::AUD_SndFileReader(std::string filename) :
- m_position(0)
-{
- SF_INFO sfinfo;
-
- sfinfo.format = 0;
- m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
- m_length = sfinfo.frames;
- m_seekable = sfinfo.seekable;
-}
-
-AUD_SndFileReader::AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer) :
- m_position(0),
- m_membuffer(buffer),
- m_memoffset(0)
-{
- m_vio.get_filelen = vio_get_filelen;
- m_vio.read = vio_read;
- m_vio.seek = vio_seek;
- m_vio.tell = vio_tell;
- m_vio.write = NULL;
-
- SF_INFO sfinfo;
-
- sfinfo.format = 0;
- m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
- m_length = sfinfo.frames;
- m_seekable = sfinfo.seekable;
-}
-
-AUD_SndFileReader::~AUD_SndFileReader()
-{
- sf_close(m_sndfile);
-}
-
-bool AUD_SndFileReader::isSeekable() const
-{
- return m_seekable;
-}
-
-void AUD_SndFileReader::seek(int position)
-{
- if(m_seekable)
- {
- position = sf_seek(m_sndfile, position, SEEK_SET);
- m_position = position;
- }
-}
-
-int AUD_SndFileReader::getLength() const
-{
- return m_length;
-}
-
-int AUD_SndFileReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SndFileReader::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_SndFileReader::read(int& length, bool& eos, sample_t* buffer)
-{
- int olen = length;
-
- length = sf_readf_float(m_sndfile, buffer, length);
-
- m_position += length;
-
- eos = length < olen;
-}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
deleted file mode 100644
index 5cac5051ee2..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileReader.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEREADER_H__
-#define __AUD_SNDFILEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <sndfile.h>
-#include <boost/shared_ptr.hpp>
-
-typedef sf_count_t (*sf_read_f)(SNDFILE *sndfile, void *ptr, sf_count_t frames);
-
-/**
- * This class reads a sound file via libsndfile.
- */
-class AUD_SndFileReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The sample count in the file.
- */
- int m_length;
-
- /**
- * Whether the file is seekable.
- */
- bool m_seekable;
-
- /**
- * The specification of the audio data.
- */
- AUD_Specs m_specs;
-
- /**
- * The sndfile.
- */
- SNDFILE* m_sndfile;
-
- /**
- * The virtual IO structure for memory file reading.
- */
- SF_VIRTUAL_IO m_vio;
-
- /**
- * The pointer to the memory file.
- */
- boost::shared_ptr<AUD_Buffer> m_membuffer;
-
- /**
- * The current reading pointer of the memory file.
- */
- int m_memoffset;
-
- // Functions for libsndfile virtual IO functionality
- static sf_count_t vio_get_filelen(void *user_data);
- static sf_count_t vio_seek(sf_count_t offset, int whence, void *user_data);
- static sf_count_t vio_read(void *ptr, sf_count_t count, void *user_data);
- static sf_count_t vio_tell(void *user_data);
-
- // hide copy constructor and operator=
- AUD_SndFileReader(const AUD_SndFileReader&);
- AUD_SndFileReader& operator=(const AUD_SndFileReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param filename The path to the file to be read.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with libsndfile.
- */
- AUD_SndFileReader(std::string filename);
-
- /**
- * Creates a new reader.
- * \param buffer The buffer to read from.
- * \exception AUD_Exception Thrown if the buffer specified cannot be read
- * with libsndfile.
- */
- AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer);
-
- /**
- * Destroys the reader and closes the file.
- */
- virtual ~AUD_SndFileReader();
-
- 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, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SNDFILEREADER_H__
diff --git a/intern/audaspace/sndfile/AUD_SndFileWriter.cpp b/intern/audaspace/sndfile/AUD_SndFileWriter.cpp
deleted file mode 100644
index da3464751cb..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileWriter.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileWriter.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileWriter.h"
-
-#include <cstring>
-
-static const char* fileopen_error = "AUD_SndFileWriter: File couldn't be written.";
-static const char* format_error = "AUD_SndFileWriter: Unsupported format.";
-
-AUD_SndFileWriter::AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs,
- AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
- m_specs(specs)
-{
- SF_INFO sfinfo;
-
- sfinfo.channels = specs.channels;
- sfinfo.samplerate = int(specs.rate);
-
- switch(format)
- {
- case AUD_CONTAINER_FLAC:
- sfinfo.format = SF_FORMAT_FLAC;
- switch(specs.format)
- {
- case AUD_FORMAT_S16:
- sfinfo.format |= SF_FORMAT_PCM_16;
- break;
- case AUD_FORMAT_S24:
- sfinfo.format |= SF_FORMAT_PCM_24;
- break;
- case AUD_FORMAT_S32:
- sfinfo.format |= SF_FORMAT_PCM_32;
- break;
- case AUD_FORMAT_FLOAT32:
- sfinfo.format |= SF_FORMAT_FLOAT;
- break;
- case AUD_FORMAT_FLOAT64:
- sfinfo.format |= SF_FORMAT_DOUBLE;
- break;
- default:
- sfinfo.format = 0;
- break;
- }
- break;
- case AUD_CONTAINER_OGG:
- if(codec == AUD_CODEC_VORBIS)
- sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
- else
- sfinfo.format = 0;
- break;
- case AUD_CONTAINER_WAV:
- sfinfo.format = SF_FORMAT_WAV;
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- sfinfo.format |= SF_FORMAT_PCM_U8;
- break;
- case AUD_FORMAT_S16:
- sfinfo.format |= SF_FORMAT_PCM_16;
- break;
- case AUD_FORMAT_S24:
- sfinfo.format |= SF_FORMAT_PCM_24;
- break;
- case AUD_FORMAT_S32:
- sfinfo.format |= SF_FORMAT_PCM_32;
- break;
- case AUD_FORMAT_FLOAT32:
- sfinfo.format |= SF_FORMAT_FLOAT;
- break;
- case AUD_FORMAT_FLOAT64:
- sfinfo.format |= SF_FORMAT_DOUBLE;
- break;
- default:
- sfinfo.format = 0;
- break;
- }
- break;
- default:
- sfinfo.format = 0;
- break;
- }
-
- if(sfinfo.format == 0)
- AUD_THROW(AUD_ERROR_SPECS, format_error);
-
- m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-}
-
-AUD_SndFileWriter::~AUD_SndFileWriter()
-{
- sf_close(m_sndfile);
-}
-
-int AUD_SndFileWriter::getPosition() const
-{
- return m_position;
-}
-
-AUD_DeviceSpecs AUD_SndFileWriter::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_SndFileWriter::write(unsigned int length, sample_t* buffer)
-{
- length = sf_writef_float(m_sndfile, buffer, length);
-
- m_position += length;
-}
diff --git a/intern/audaspace/sndfile/AUD_SndFileWriter.h b/intern/audaspace/sndfile/AUD_SndFileWriter.h
deleted file mode 100644
index 0cadbd19a09..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileWriter.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/sndfile/AUD_SndFileWriter.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEWRITER_H__
-#define __AUD_SNDFILEWRITER_H__
-
-#include "AUD_IWriter.h"
-
-#include <string>
-#include <sndfile.h>
-
-/**
- * This class writes a sound file via libsndfile.
- */
-class AUD_SndFileWriter : public AUD_IWriter
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The sndfile.
- */
- SNDFILE* m_sndfile;
-
- // hide copy constructor and operator=
- AUD_SndFileWriter(const AUD_SndFileWriter&);
- AUD_SndFileWriter& operator=(const AUD_SndFileWriter&);
-
-public:
- /**
- * Creates a new writer.
- * \param filename The path to the file to be read.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \exception AUD_Exception Thrown if the file specified cannot be written
- * with libsndfile.
- */
- AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
-
- /**
- * Destroys the writer and closes the file.
- */
- virtual ~AUD_SndFileWriter();
-
- virtual int getPosition() const;
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual void write(unsigned int length, sample_t* buffer);
-};
-
-#endif //__AUD_SNDFILEWRITER_H__
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 6f8274fabc8..98fb4f47339 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -35,8 +35,8 @@
#define SOUND_WAVE_SAMPLES_PER_SECOND 250
-#ifdef WITH_SYSTEM_AUDASPACE
-# include AUD_DEVICE_H
+#if defined(WITH_AUDASPACE)
+# include <AUD_Device.h>
#endif
struct bSound;
@@ -84,7 +84,7 @@ void BKE_sound_copy_data(struct Main *bmain, struct bSound *sound_dst, const str
void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool lib_local);
-#if defined(__AUD_C_API_H__) || defined(WITH_SYSTEM_AUDASPACE)
+#if defined(WITH_AUDASPACE)
AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
#endif
@@ -149,6 +149,4 @@ float BKE_sound_get_length(struct bSound *sound);
char **BKE_sound_get_device_names(void);
-bool BKE_sound_is_jack_supported(void);
-
#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2a3d4c9fed7..db4c44a586e 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -333,7 +333,7 @@ if(WIN32)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 148fc3827e0..478b854c4df 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -59,7 +59,7 @@
#include "BKE_library.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "RNA_access.h"
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index eab80f06c09..18c721c8e3f 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -91,7 +91,7 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
/* mutable state for sequencer */
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 45d1f969d64..a617d5aa9ac 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -48,13 +48,11 @@
#include "DNA_speaker_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
-# include AUD_SEQUENCE_H
-# include AUD_HANDLE_H
-# include AUD_SPECIAL_H
-# ifdef WITH_SYSTEM_AUDASPACE
-# include "../../../intern/audaspace/intern/AUD_Set.h"
-# endif
+# include <AUD_Sound.h>
+# include <AUD_Sequence.h>
+# include <AUD_Handle.h>
+# include <AUD_Special.h>
+# include "../../../intern/audaspace/intern/AUD_Set.h"
#endif
#include "BKE_global.h"
@@ -302,7 +300,6 @@ void BKE_sound_exit_once(void)
sound_device = NULL;
AUD_exitOnce();
-#ifdef WITH_SYSTEM_AUDASPACE
if (audio_device_names != NULL) {
int i;
for (i = 0; audio_device_names[i]; i++) {
@@ -311,7 +308,6 @@ void BKE_sound_exit_once(void)
free(audio_device_names);
audio_device_names = NULL;
}
-#endif
}
/* XXX unused currently */
@@ -907,28 +903,12 @@ float BKE_sound_get_length(bSound *sound)
char **BKE_sound_get_device_names(void)
{
if (audio_device_names == NULL) {
-#ifdef WITH_SYSTEM_AUDASPACE
audio_device_names = AUD_getDeviceNames();
-#else
- static const char *names[] = {
- "Null", "SDL", "OpenAL", "JACK", NULL
- };
- audio_device_names = (char **)names;
-#endif
}
return audio_device_names;
}
-bool BKE_sound_is_jack_supported(void)
-{
-#ifdef WITH_SYSTEM_AUDASPACE
- return 1;
-#else
- return (bool)AUD_isJackSupported();
-#endif
-}
-
#else /* WITH_AUDASPACE */
#include "BLI_utildefines.h"
@@ -975,5 +955,4 @@ void BKE_sound_set_scene_sound_pan(void *UNUSED(handle), float UNUSED(pan), char
void BKE_sound_set_scene_volume(struct Scene *UNUSED(scene), float UNUSED(volume)) {}
void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle), float UNUSED(pitch), char UNUSED(animated)) {}
float BKE_sound_get_length(struct bSound *UNUSED(sound)) { return 0; }
-bool BKE_sound_is_jack_supported(void) { return false; }
#endif /* WITH_AUDASPACE */
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 156b74f5c3d..4a226dbda11 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -45,8 +45,8 @@
#include "BLI_blenlib.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
-# include AUD_SPECIAL_H
+# include <AUD_Device.h>
+# include <AUD_Special.h>
#endif
#include "BLI_utildefines.h"
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 1e1d08a3a9c..bf42316289f 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -2971,11 +2971,8 @@ void init_userdef_do_versions(void)
if (U.image_draw_method == 0)
U.image_draw_method = IMAGE_DRAW_METHOD_2DTEXTURE;
- // keep the following until the new audaspace is default to be built with
-#ifdef WITH_SYSTEM_AUDASPACE
// we default to the first audio device
U.audiodevice = 0;
-#endif
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
diff --git a/source/blender/editors/sound/CMakeLists.txt b/source/blender/editors/sound/CMakeLists.txt
index 535cd579030..9efdf11e8d7 100644
--- a/source/blender/editors/sound/CMakeLists.txt
+++ b/source/blender/editors/sound/CMakeLists.txt
@@ -39,7 +39,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index d103530fa81..ecc00f4b7e5 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -67,7 +67,7 @@
#include "WM_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "ED_sound.h"
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index 64ce1704b07..2840324e65e 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -49,7 +49,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 09e38579c21..56b67f921fc 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -36,7 +36,7 @@
#include <float.h>
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "MEM_guardedalloc.h"
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index 6dce962ee02..6b8108a1265 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -54,7 +54,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 46f212e3679..49c687632f8 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -69,7 +69,7 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include AUD_SEQUENCE_H
+# include <AUD_Sequence.h>
#endif
/* own include */
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 7c9d10a4e2c..fa01df2cbda 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -233,7 +233,7 @@ if(WITH_IMAGE_FRAMESERVER)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index ab94c8e303b..23f858f129b 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -65,7 +65,7 @@
#ifdef WITH_QUICKTIME
# include "quicktime_export.h"
-# include AUD_TYPES_H
+# include <AUD_Types.h>
#endif
#ifdef WITH_FFMPEG
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 438735d371d..628adbddd36 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -519,7 +519,6 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
int totitem = 0;
EnumPropertyItem *item = NULL;
-#ifdef WITH_SYSTEM_AUDASPACE
int i;
char **names = BKE_sound_get_device_names();
@@ -528,31 +527,6 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
EnumPropertyItem new_item = {i, names[i], 0, names[i], names[i]};
RNA_enum_item_add(&item, &totitem, &new_item);
}
-#else
- /* NONE */
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
-
-#ifdef WITH_SDL
-# ifdef WITH_SDL_DYNLOAD
- if (sdlewInit() == SDLEW_SUCCESS)
-# endif
- {
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
- }
- index++;
-#endif
-
-#ifdef WITH_OPENAL
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
-#endif
-
-#ifdef WITH_JACK
- if (BKE_sound_is_jack_supported()) {
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
- }
- index++;
-#endif
-#endif
/* may be unused */
UNUSED_VARS(index, audio_device_items);
diff --git a/source/blender/quicktime/CMakeLists.txt b/source/blender/quicktime/CMakeLists.txt
index f853c35457f..cee2cea99fb 100644
--- a/source/blender/quicktime/CMakeLists.txt
+++ b/source/blender/quicktime/CMakeLists.txt
@@ -52,7 +52,7 @@ set(SRC
add_definitions(-DWITH_QUICKTIME)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 1ac3c58f888..d2508fe108a 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -35,7 +35,7 @@
#include "DNA_userdef_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
#include "BLI_utildefines.h"
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index cfa97a9e177..0894f246445 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -97,7 +97,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index fdcded8e50a..2c766efc6a2 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -77,10 +77,10 @@
#include "WM_api.h" /* only for WM_main_playanim */
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
-# include AUD_HANDLE_H
-# include AUD_SOUND_H
-# include AUD_SPECIAL_H
+# include <AUD_Device.h>
+# include <AUD_Handle.h>
+# include <AUD_Sound.h>
+# include <AUD_Special.h>
static AUD_Sound *source = NULL;
static AUD_Handle *playback_handle = NULL;
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 4f0e64b0955..bd07961c556 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -91,6 +91,12 @@ list(APPEND BLENDER_LINK_LIBS
blenkernel_blc
)
+if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ list(APPEND BLENDER_LINK_LIBS
+ audaspace
+ audaspace-py)
+endif()
+
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND BLENDER_LINK_LIBS extern_binreloc)
endif()
@@ -150,6 +156,8 @@ endif()
bf_blenfont
bf_blentranslation
bf_intern_audaspace
+ audaspace
+ audaspace-py
blenkernel_blc
bf_bmesh
bf_blenlib
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 99f3d0639f3..4e8f0eba9b7 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -101,7 +101,7 @@ typedef void * wmUIHandlerRemoveFunc;
}
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
static BlendFileData *load_game_data(const char *filename)
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index aaeb2e10462..42293050753 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -56,7 +56,7 @@ set(SRC
add_definitions(${GL_DEFINITIONS})
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index 4db9fcebd06..7d6195e3c38 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -113,7 +113,7 @@ if(WITH_BULLET)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 974dcbca95b..d78ea4eed54 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -42,7 +42,7 @@
#include "KX_ConvertActuators.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
+# include <AUD_Sound.h>
#endif
// Actuators
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index 6d6d53b1e17..5bce9fcd248 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -95,7 +95,7 @@ if(WITH_INTERNATIONAL)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index ddb04e9f84d..1b6b6defdf9 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -99,7 +99,7 @@ extern "C"
#include "GHOST_Rect.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 417f54cc8b9..cb7c0180f30 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -244,7 +244,7 @@ if(WITH_CODEC_FFMPEG)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index d858097abef..04ec3f9cd04 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -37,14 +37,12 @@
#include "KX_SoundActuator.h"
#ifdef WITH_AUDASPACE
-# ifdef WITH_SYSTEM_AUDASPACE
typedef float sample_t;
-# include AUD_PYTHON_H
-# endif
-# include AUD_SOUND_H
-# include AUD_SPECIAL_H
-# include AUD_DEVICE_H
-# include AUD_HANDLE_H
+# include <python/PyAPI.h>
+# include <AUD_Sound.h>
+# include <AUD_Special.h>
+# include <AUD_Device.h>
+# include <AUD_Handle.h>
#endif
#include "KX_GameObject.h"
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 5ec2fda722f..4f3e6f707e0 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -35,8 +35,8 @@
#include "SCA_IActuator.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
-# include AUD_HANDLE_H
+# include <AUD_Sound.h>
+# include <AUD_Handle.h>
#endif
#include "BKE_sound.h"