svn merge -r39781:39792 https://svn.blender.org/svnroot/bf-blender/trunk/blender...
authorCampbell Barton <ideasman42@gmail.com>
Thu, 1 Sep 2011 00:35:30 +0000 (00:35 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 1 Sep 2011 00:35:30 +0000 (00:35 +0000)
432 files changed:
doc/python_api/rst/bge.types.rst
intern/audaspace/CMakeLists.txt
intern/audaspace/FX/AUD_AccumulatorFactory.cpp
intern/audaspace/FX/AUD_AccumulatorFactory.h
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
intern/audaspace/FX/AUD_BaseIIRFilterReader.h
intern/audaspace/FX/AUD_ButterworthFactory.cpp
intern/audaspace/FX/AUD_ButterworthFactory.h
intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
intern/audaspace/FX/AUD_DelayFactory.cpp
intern/audaspace/FX/AUD_DelayFactory.h
intern/audaspace/FX/AUD_DelayReader.cpp
intern/audaspace/FX/AUD_DelayReader.h
intern/audaspace/FX/AUD_DoubleFactory.cpp
intern/audaspace/FX/AUD_DoubleFactory.h
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_DoubleReader.h
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_DynamicIIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EffectFactory.cpp
intern/audaspace/FX/AUD_EffectFactory.h
intern/audaspace/FX/AUD_EffectReader.cpp
intern/audaspace/FX/AUD_EffectReader.h
intern/audaspace/FX/AUD_EnvelopeFactory.cpp
intern/audaspace/FX/AUD_EnvelopeFactory.h
intern/audaspace/FX/AUD_FaderFactory.cpp
intern/audaspace/FX/AUD_FaderFactory.h
intern/audaspace/FX/AUD_FaderReader.cpp
intern/audaspace/FX/AUD_FaderReader.h
intern/audaspace/FX/AUD_HighpassFactory.cpp
intern/audaspace/FX/AUD_HighpassFactory.h
intern/audaspace/FX/AUD_IIRFilterFactory.cpp
intern/audaspace/FX/AUD_IIRFilterFactory.h
intern/audaspace/FX/AUD_IIRFilterReader.cpp
intern/audaspace/FX/AUD_IIRFilterReader.h
intern/audaspace/FX/AUD_LimiterFactory.cpp
intern/audaspace/FX/AUD_LimiterFactory.h
intern/audaspace/FX/AUD_LimiterReader.cpp
intern/audaspace/FX/AUD_LimiterReader.h
intern/audaspace/FX/AUD_LoopFactory.cpp
intern/audaspace/FX/AUD_LoopFactory.h
intern/audaspace/FX/AUD_LoopReader.cpp
intern/audaspace/FX/AUD_LoopReader.h
intern/audaspace/FX/AUD_LowpassFactory.cpp
intern/audaspace/FX/AUD_LowpassFactory.h
intern/audaspace/FX/AUD_PingPongFactory.cpp
intern/audaspace/FX/AUD_PingPongFactory.h
intern/audaspace/FX/AUD_PitchFactory.cpp
intern/audaspace/FX/AUD_PitchFactory.h
intern/audaspace/FX/AUD_PitchReader.cpp
intern/audaspace/FX/AUD_PitchReader.h
intern/audaspace/FX/AUD_RectifyFactory.cpp
intern/audaspace/FX/AUD_RectifyFactory.h
intern/audaspace/FX/AUD_ReverseFactory.cpp
intern/audaspace/FX/AUD_ReverseFactory.h
intern/audaspace/FX/AUD_ReverseReader.cpp
intern/audaspace/FX/AUD_ReverseReader.h
intern/audaspace/FX/AUD_SquareFactory.cpp
intern/audaspace/FX/AUD_SquareFactory.h
intern/audaspace/FX/AUD_SumFactory.cpp
intern/audaspace/FX/AUD_SumFactory.h
intern/audaspace/FX/AUD_SuperposeFactory.cpp
intern/audaspace/FX/AUD_SuperposeFactory.h
intern/audaspace/FX/AUD_SuperposeReader.cpp
intern/audaspace/FX/AUD_SuperposeReader.h
intern/audaspace/FX/AUD_VolumeFactory.cpp
intern/audaspace/FX/AUD_VolumeFactory.h
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/OpenAL/AUD_OpenALDevice.h
intern/audaspace/Python/AUD_PyAPI.cpp
intern/audaspace/Python/AUD_PyAPI.h
intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
intern/audaspace/SRC/AUD_SRCResampleFactory.h
intern/audaspace/SRC/AUD_SRCResampleReader.cpp
intern/audaspace/SRC/AUD_SRCResampleReader.h
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp [new file with mode: 0644]
intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h [new file with mode: 0644]
intern/audaspace/fftw/AUD_BandPassReader.cpp
intern/audaspace/intern/AUD_3DMath.h
intern/audaspace/intern/AUD_AnimateableProperty.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Buffer.cpp
intern/audaspace/intern/AUD_Buffer.h
intern/audaspace/intern/AUD_BufferReader.cpp
intern/audaspace/intern/AUD_BufferReader.h
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
intern/audaspace/intern/AUD_ChannelMapperFactory.h
intern/audaspace/intern/AUD_ChannelMapperReader.cpp
intern/audaspace/intern/AUD_ChannelMapperReader.h
intern/audaspace/intern/AUD_ConverterFactory.cpp
intern/audaspace/intern/AUD_ConverterFactory.h
intern/audaspace/intern/AUD_ConverterFunctions.cpp
intern/audaspace/intern/AUD_ConverterReader.cpp
intern/audaspace/intern/AUD_ConverterReader.h
intern/audaspace/intern/AUD_FileFactory.cpp
intern/audaspace/intern/AUD_FileFactory.h
intern/audaspace/intern/AUD_FileWriter.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_FileWriter.h [new file with mode: 0644]
intern/audaspace/intern/AUD_I3DDevice.h
intern/audaspace/intern/AUD_I3DHandle.h [new file with mode: 0644]
intern/audaspace/intern/AUD_IDevice.h
intern/audaspace/intern/AUD_IFactory.h
intern/audaspace/intern/AUD_IReader.h
intern/audaspace/intern/AUD_IWriter.h [new file with mode: 0644]
intern/audaspace/intern/AUD_JOSResampleFactory.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_JOSResampleReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleFactory.cpp
intern/audaspace/intern/AUD_LinearResampleFactory.h
intern/audaspace/intern/AUD_LinearResampleReader.cpp
intern/audaspace/intern/AUD_LinearResampleReader.h
intern/audaspace/intern/AUD_Mixer.cpp
intern/audaspace/intern/AUD_Mixer.h
intern/audaspace/intern/AUD_MixerFactory.cpp
intern/audaspace/intern/AUD_MixerFactory.h
intern/audaspace/intern/AUD_NULLDevice.cpp
intern/audaspace/intern/AUD_NULLDevice.h
intern/audaspace/intern/AUD_ReadDevice.cpp
intern/audaspace/intern/AUD_ReadDevice.h
intern/audaspace/intern/AUD_Reference.h
intern/audaspace/intern/AUD_ReferenceHandler.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ResampleReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ResampleReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerEntry.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerFactory.cpp
intern/audaspace/intern/AUD_SequencerFactory.h
intern/audaspace/intern/AUD_SequencerHandle.h [new file with mode: 0644]
intern/audaspace/intern/AUD_SequencerReader.cpp
intern/audaspace/intern/AUD_SequencerReader.h
intern/audaspace/intern/AUD_SilenceFactory.cpp
intern/audaspace/intern/AUD_SilenceFactory.h
intern/audaspace/intern/AUD_SilenceReader.cpp
intern/audaspace/intern/AUD_SilenceReader.h
intern/audaspace/intern/AUD_SinusFactory.cpp
intern/audaspace/intern/AUD_SinusFactory.h
intern/audaspace/intern/AUD_SinusReader.cpp
intern/audaspace/intern/AUD_SinusReader.h
intern/audaspace/intern/AUD_SoftwareDevice.cpp
intern/audaspace/intern/AUD_SoftwareDevice.h
intern/audaspace/intern/AUD_Space.h
intern/audaspace/intern/AUD_StreamBufferFactory.cpp
intern/audaspace/intern/AUD_StreamBufferFactory.h
intern/audaspace/jack/AUD_JackDevice.cpp
intern/audaspace/jack/AUD_JackDevice.h
intern/audaspace/sndfile/AUD_SndFileFactory.cpp
intern/audaspace/sndfile/AUD_SndFileFactory.h
intern/audaspace/sndfile/AUD_SndFileReader.cpp
intern/audaspace/sndfile/AUD_SndFileReader.h
intern/audaspace/sndfile/AUD_SndFileWriter.cpp [new file with mode: 0644]
intern/audaspace/sndfile/AUD_SndFileWriter.h [new file with mode: 0644]
release/datafiles/blenderbuttons
release/scripts/modules/bpy_types.py
release/scripts/presets/ffmpeg/DV.py
release/scripts/presets/ffmpeg/DVD.py
release/scripts/presets/ffmpeg/SVCD.py
release/scripts/presets/ffmpeg/VCD.py
release/scripts/startup/bl_operators/nla.py
release/scripts/startup/bl_operators/object.py
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_data_armature.py
release/scripts/startup/bl_ui/properties_data_speaker.py [new file with mode: 0644]
release/scripts/startup/bl_ui/properties_game.py
release/scripts/startup/bl_ui/properties_object_constraint.py
release/scripts/startup/bl_ui/properties_render.py
release/scripts/startup/bl_ui/properties_scene.py
release/scripts/startup/bl_ui/space_dopesheet.py
release/scripts/startup/bl_ui/space_graph.py
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_nla.py
release/scripts/startup/bl_ui/space_sequencer.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_action.h
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_constraint.h
source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/BKE_nla.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/BKE_speaker.h [new file with mode: 0644]
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/fmodifier.c
source/blender/blenkernel/intern/gpencil.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/nla.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/speaker.c [new file with mode: 0644]
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/collada/AnimationExporter.cpp [new file with mode: 0644]
source/blender/collada/AnimationExporter.h [new file with mode: 0644]
source/blender/collada/AnimationImporter.cpp
source/blender/collada/AnimationImporter.h
source/blender/collada/ArmatureExporter.cpp
source/blender/collada/ArmatureExporter.h
source/blender/collada/ArmatureImporter.cpp
source/blender/collada/ArmatureImporter.h
source/blender/collada/CMakeLists.txt
source/blender/collada/CameraExporter.cpp
source/blender/collada/DocumentExporter.cpp
source/blender/collada/DocumentImporter.cpp
source/blender/collada/DocumentImporter.h
source/blender/collada/EffectExporter.cpp
source/blender/collada/ExtraHandler.cpp
source/blender/collada/ExtraHandler.h
source/blender/collada/GeometryExporter.h
source/blender/collada/LightExporter.cpp
source/blender/collada/SkinInfo.cpp
source/blender/collada/TransformReader.cpp
source/blender/collada/TransformWriter.cpp
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/anim_intern.h
source/blender/editors/animation/anim_ipo_utils.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/anim_ops.c
source/blender/editors/animation/drivers.c
source/blender/editors/animation/fmodifier_ui.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/animation/keyframes_general.c
source/blender/editors/animation/keyframing.c
source/blender/editors/animation/keyingsets.c
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/armature_ops.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/poseSlide.c
source/blender/editors/armature/poseUtils.c
source/blender/editors/armature/poselib.c
source/blender/editors/armature/poseobject.c
source/blender/editors/datafiles/blenderbuttons.c
source/blender/editors/datafiles/startup.blend.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/editaction_gpencil.c
source/blender/editors/gpencil/gpencil_buttons.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_intern.h
source/blender/editors/gpencil/gpencil_ops.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_gpencil.h
source/blender/editors/include/ED_keyframes_draw.h
source/blender/editors/include/ED_keyframes_edit.h
source/blender/editors/include/ED_keyframing.h
source/blender/editors/include/ED_markers.h
source/blender/editors/include/UI_icons.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_anim.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/resources.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_select.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sound/CMakeLists.txt
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_action/action_draw.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_intern.h
source/blender/editors/space_action/action_ops.c
source/blender/editors/space_action/action_select.c
source/blender/editors/space_action/space_action.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_graph/graph_buttons.c
source/blender/editors/space_graph/graph_draw.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_graph/graph_ops.c
source/blender/editors/space_graph/graph_select.c
source/blender/editors/space_graph/graph_utils.c
source/blender/editors/space_graph/space_graph.c
source/blender/editors/space_logic/logic_window.c
source/blender/editors/space_nla/nla_buttons.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_nla/nla_draw.c
source/blender/editors/space_nla/nla_edit.c
source/blender/editors/space_nla/nla_intern.h
source/blender/editors/space_nla/nla_ops.c
source/blender/editors/space_nla/nla_select.c
source/blender/editors/space_nla/space_nla.c
source/blender/editors/space_outliner/outliner_draw.c
source/blender/editors/space_outliner/outliner_edit.c
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_ops.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_sequencer/sequencer_add.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_sequencer/space_sequencer.c
source/blender/editors/space_text/text_draw.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_time/time_intern.h
source/blender/editors/space_time/time_ops.c
source/blender/editors/space_view3d/drawanimviz.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_ops.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_actuator_types.h
source/blender/makesdna/DNA_anim_types.h
source/blender/makesdna/DNA_armature_types.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_gpencil_types.h
source/blender/makesdna/DNA_ipo_types.h
source/blender/makesdna/DNA_nla_types.h
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_types.h
source/blender/makesdna/DNA_sound_types.h
source/blender/makesdna/DNA_speaker_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_actuator.c
source/blender/makesrna/intern/rna_animation.c
source/blender/makesrna/intern/rna_animation_api.c
source/blender/makesrna/intern/rna_animviz.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_curve.c
source/blender/makesrna/intern/rna_fcurve.c
source/blender/makesrna/intern/rna_gpencil.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_nla.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_pose.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sequencer.c
source/blender/makesrna/intern/rna_sound.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_speaker.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_userdef.c
source/blender/render/intern/source/pipeline.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_ActionActuator.h
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_ArmatureObject.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_DeformableGameObject.cpp
source/gameengine/Converter/BL_DeformableGameObject.h
source/gameengine/Converter/BL_ShapeActionActuator.cpp
source/gameengine/Converter/BL_ShapeActionActuator.h
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_ShapeDeformer.h
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/CMakeLists.txt
source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
source/gameengine/Converter/KX_BlenderScalarInterpolator.h
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.h
source/gameengine/Converter/KX_ConvertActuators.cpp
source/gameengine/Converter/KX_IpoConvert.cpp
source/gameengine/Converter/KX_IpoConvert.h
source/gameengine/Converter/SConscript
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/Ketsji/BL_Action.cpp [new file with mode: 0644]
source/gameengine/Ketsji/BL_Action.h [new file with mode: 0644]
source/gameengine/Ketsji/BL_ActionManager.cpp [new file with mode: 0644]
source/gameengine/Ketsji/BL_ActionManager.h [new file with mode: 0644]
source/gameengine/Ketsji/CMakeLists.txt
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.h
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_SoundActuator.h
source/gameengine/Ketsji/SConscript
source/gameengine/SceneGraph/SG_IObject.cpp
source/gameengine/SceneGraph/SG_IObject.h

index 36ef9154e1753640daa12a7c5b79662f659747ef..d1fc8593e42fd53cb529ee5d85fdc2fabf9d87ad 100644 (file)
@@ -1539,6 +1539,63 @@ Game Types (bge.types)
       Return the value matching key, or the default value if its not found.
       :return: The key value or a default.
 
+   .. method:: playAction(name, start_frame, end_frame, layer=0, priority=0 blendin=0, play_mode=ACT_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0)
+
+      Plays an action.
+         
+      :arg name: the name of the action
+         :type name: string
+      :arg start: the start frame of the action
+         :type start: float
+      :arg end: the end frame of the action
+         :type end: float
+      :arg layer: the layer the action will play in (actions in different layers are added/blended together)
+         :type layer: integer
+      :arg priority: only play this action if there isn't an action currently playing in this layer with a higher (lower number) priority
+         :type priority: integer
+      :arg blendin: the amount of blending between this animation and the previous one on this layer
+         :type blendin: float
+      :arg play_mode: the play mode
+         :type play_mode: KX_ACTION_PLAY, KX_ACTION_LOOP, or KX_ACTION_PING_PONG
+      :arg layer_weight: how much of the previous layer to use for blending (0 = add)
+         :type layer_weight: float
+      :arg ipo_flags: flags for the old IPO behaviors (force, etc)
+         :type ipo_flags: int bitfield
+      :arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
+         :type speed: float
+
+   .. method:: stopAction(layer=0)
+      
+         Stop playing the action on the given layer.
+         
+         :arg layer: The layer to stop playing.
+         :type layer: integer
+         
+   .. method:: getActionFrame(layer=0)
+   
+      Gets the current frame of the action playing in the supplied layer.
+         
+         :arg layer: The layer that you want to get the frame from.
+         :type layer: integer
+         
+         :return: The current frame of the action
+         
+   .. method:: setActionFrame(frame, layer=0)
+   
+      Set the current frame of the action playing in the supplied layer.
+         
+         :arg layer: The layer where you want to set the frame
+         :type layer: integer
+         :arg frame: The frame to set the action to
+         :type frame: float
+
+   .. method:: isPlayingAction(layer=0)
+   
+       Checks to see if there is an action playing in the given layer.
+          
+          :arg layer: The layer to check for a playing action.
+          :type layer: integer
+
 .. class:: KX_IpoActuator(SCA_IActuator)
 
    IPO actuator activates an animation.
index 7eef13b103beb9e9cdaa74656bce3bd99a548d08..8b7cb1d9e691ab80de64330ddeb101953db5d50c 100644 (file)
@@ -41,6 +41,8 @@ set(SRC
        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
@@ -66,6 +68,8 @@ set(SRC
        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
@@ -82,14 +86,21 @@ set(SRC
        intern/AUD_ConverterFunctions.h
        intern/AUD_ConverterReader.cpp
        intern/AUD_ConverterReader.h
-       intern/AUD_DefaultMixer.cpp
-       intern/AUD_DefaultMixer.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_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
@@ -104,9 +115,15 @@ set(SRC
        intern/AUD_ReadDevice.cpp
        intern/AUD_ReadDevice.h
        intern/AUD_Reference.h
-       intern/AUD_ResampleFactory.h
+       intern/AUD_ReferenceHandler.cpp
+       intern/AUD_ResampleReader.cpp
+       intern/AUD_ResampleReader.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_SilenceFactory.cpp
@@ -131,6 +148,8 @@ set(SRC
        FX/AUD_DelayReader.h
        FX/AUD_DoubleFactory.h
        FX/AUD_DoubleReader.h
+       FX/AUD_DynamicIIRFilterFactory.h
+       FX/AUD_DynamicIIRFilterReader.h
        FX/AUD_EffectFactory.h
        FX/AUD_EffectReader.h
        FX/AUD_EnvelopeFactory.h
@@ -168,9 +187,11 @@ if(WITH_CODEC_FFMPEG)
        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
        )
 endif()
 
@@ -230,9 +251,11 @@ if(WITH_CODEC_SNDFILE)
        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()
 
index d60924958b162ea25af477a565db5d7bac25c66b..0dffa7fc9ea57f8916e07c8bb9c3bd41cf3320ac 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_AccumulatorFactory.h"
 #include "AUD_CallbackIIRFilterReader.h"
 
-sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_AccumulatorFactory::accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
 {
        float in = reader->x(0);
        float lastin = reader->x(-1);
@@ -42,7 +42,7 @@ sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* us
        return out;
 }
 
-sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_AccumulatorFactory::accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
 {
        float in = reader->x(0);
        float lastin = reader->x(-1);
@@ -52,14 +52,14 @@ sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
        return out;
 }
 
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory,
                                                                                           bool additive) :
                AUD_EffectFactory(factory),
                m_additive(additive)
 {
 }
 
-AUD_IReader* AUD_AccumulatorFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_AccumulatorFactory::createReader()
 {
        return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
                                                        m_additive ? accumulatorFilterAdditive : accumulatorFilter);
index 3c3b32ce0711d5c0b6f6a108515093accf54f41a..95246ef534110ae5009a86fb928cdac26b905615 100644 (file)
 #define AUD_ACCUMULATORFACTORY
 
 #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
 {
@@ -55,9 +60,12 @@ public:
         * \param factory The input factory.
         * \param additive Whether the accumulator is additive.
         */
-       AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
+       AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory, bool additive = false);
+
+       virtual AUD_Reference<AUD_IReader> createReader();
 
-       virtual AUD_IReader* createReader() const;
+       static sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless);
+       static sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
 };
 
 #endif //AUD_ACCUMULATORFACTORY
index 563722d921397b00496e0310fba4b851c9f93900..29ff6d90080b17df533cec5b3432ccecf03037bd 100644 (file)
 
 #include <cstring>
 
-#define CC m_channels + m_channel
+#define CC m_specs.channels + m_channel
 
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_IReader* reader, int in,
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in,
                                                                                                 int out) :
                AUD_EffectReader(reader),
-               m_channels(reader->getSpecs().channels),
+               m_specs(reader->getSpecs()),
                m_xlen(in), m_ylen(out),
                m_xpos(0), m_ypos(0), m_channel(0)
 {
-       m_x = new sample_t[in * m_channels];
-       m_y = new sample_t[out * m_channels];
+       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) * in * m_channels);
-       memset(m_y, 0, sizeof(sample_t) * out * m_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()
@@ -55,24 +55,77 @@ AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
        delete[] m_y;
 }
 
-void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
+void AUD_BaseIIRFilterReader::setLengths(int in, int out)
 {
-       sample_t* buf;
+       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;
 
-       int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+               m_x = new sample_t[m_xlen * m_specs.channels];
+               m_y = new sample_t[m_ylen * m_specs.channels];
 
-       m_reader->read(length, buf);
+               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(m_buffer.getSize() < length * samplesize)
-               m_buffer.resize(length * samplesize);
+       if(specs.rate != m_specs.rate)
+       {
+               m_specs = specs;
+               sampleRateChanged(m_specs.rate);
+       }
 
-       buffer = m_buffer.getBuffer();
+       m_reader->read(length, eos, buffer);
 
-       for(m_channel = 0; m_channel < m_channels; m_channel++)
+       for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
        {
                for(int i = 0; i < length; i++)
                {
-                       m_x[m_xpos * CC] = buf[i * CC];
+                       m_x[m_xpos * CC] = buffer[i * CC];
                        m_y[m_ypos * CC] = buffer[i * CC] = filter();
 
                        m_xpos = (m_xpos + 1) % m_xlen;
@@ -80,3 +133,7 @@ void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
                }
        }
 }
+
+void AUD_BaseIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
+{
+}
index 436e6469a58284ce86d875347878fc0e2fade4ee..6bf877d66dadf7f09d930ce07c94959d6a86911f 100644 (file)
@@ -42,24 +42,19 @@ class AUD_BaseIIRFilterReader : public AUD_EffectReader
 {
 private:
        /**
-        * Channel count.
+        * Specs.
         */
-       const int m_channels;
+       AUD_Specs m_specs;
 
        /**
         * Length of input samples needed.
         */
-       const int m_xlen;
+       int m_xlen;
 
        /**
         * Length of output samples needed.
         */
-       const int m_ylen;
-
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
+       int m_ylen;
 
        /**
         * The last in samples array.
@@ -97,24 +92,46 @@ protected:
         * \param in The count of past input samples needed.
         * \param out The count of past output samples needed.
         */
-       AUD_BaseIIRFilterReader(AUD_IReader* reader, int in, int out);
+       AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out);
+
+       void setLengths(int in, int out);
 
 public:
+       /**
+        * Retrieves the last input samples.
+        * \param pos The position, valid are 0 (current) or negative values.
+        * \return The sample value.
+        */
        inline sample_t x(int pos)
        {
-               return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_channels + m_channel];
+               return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_specs.channels + m_channel];
        }
 
+       /**
+        * Retrieves the last output samples.
+        * \param pos The position, valid are negative values.
+        * \return The sample value.
+        */
        inline sample_t y(int pos)
        {
-               return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_channels + m_channel];
+               return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_specs.channels + m_channel];
        }
 
        virtual ~AUD_BaseIIRFilterReader();
 
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 
+       /**
+        * Runs the filtering function.
+        * \return The current output sample value.
+        */
        virtual sample_t filter()=0;
+
+       /**
+        * Notifies the filter about a sample rate change.
+        * \param rate The new sample rate.
+        */
+       virtual void sampleRateChanged(AUD_SampleRate rate);
 };
 
 #endif //AUD_BASEIIRFILTERREADER
index ea957c81ed37733bae638771ce73de8110c6b174..4b45512ffa64c2b3dbb640796703f29a183efce1 100644 (file)
 #define BWPB41 0.76536686473
 #define BWPB42 1.84775906502
 
-AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
+AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory,
                                                                                           float frequency) :
-               AUD_EffectFactory(factory),
+               AUD_DynamicIIRFilterFactory(factory),
                m_frequency(frequency)
 {
 }
 
-AUD_IReader* AUD_ButterworthFactory::createReader() const
+void AUD_ButterworthFactory::recalculateCoefficients(AUD_SampleRate rate,
+                                                                                                        std::vector<float> &b,
+                                                                                                        std::vector<float> &a)
 {
-       AUD_IReader* reader = getReader();
-
-       // calculate coefficients
-       float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
+       float omega = 2 * tan(m_frequency * M_PI / rate);
        float o2 = omega * omega;
        float o4 = o2 * o2;
        float x1 = o2 + 2 * BWPB41 * omega + 4;
@@ -62,7 +61,6 @@ AUD_IReader* AUD_ButterworthFactory::createReader() const
        float y2 = o2 - 2 * BWPB42 * omega + 4;
        float o228 = 2 * o2 - 8;
        float norm = x1 * x2;
-       std::vector<float> a, b;
        a.push_back(1);
        a.push_back((x1 + x2) * o228 / norm);
        a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
@@ -73,6 +71,4 @@ AUD_IReader* AUD_ButterworthFactory::createReader() const
        b.push_back(6 * o4 / norm);
        b.push_back(b[1]);
        b.push_back(b[0]);
-
-       return new AUD_IIRFilterReader(reader, b, a);
 }
index c8b731449c4e90d04ca223cf6a77b35ff374436a..12d28eb40383740eafa3e75c4142b9581f11c137 100644 (file)
 #ifndef AUD_BUTTERWORTHFACTORY
 #define AUD_BUTTERWORTHFACTORY
 
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
 
 /**
- * This factory creates a butterworth filter reader.
+ * This factory creates a butterworth lowpass filter reader.
  */
-class AUD_ButterworthFactory : public AUD_EffectFactory
+class AUD_ButterworthFactory : public AUD_DynamicIIRFilterFactory
 {
 private:
        /**
@@ -55,9 +55,11 @@ public:
         * \param factory The input factory.
         * \param frequency The cutoff frequency.
         */
-       AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
+       AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency);
 
-       virtual AUD_IReader* createReader() const;
+       virtual void recalculateCoefficients(AUD_SampleRate rate,
+                                                                                std::vector<float>& b,
+                                                                                std::vector<float>& a);
 };
 
 #endif //AUD_BUTTERWORTHFACTORY
index 2f9bb7762a04af704d08badcc550ed68a4afe19e..e6c83322435dc72a2d5226afd303bd587bb44013 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "AUD_CallbackIIRFilterReader.h"
 
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader,
                                                                                                                 int in, int out,
                                                                                                                 doFilterIIR doFilter,
                                                                                                                 endFilterIIR endFilter,
index a969db7297ef0692adf236323b51d49be701ea0f..6d53edeecc2e1c90264db1701ca958a80727cc01 100644 (file)
@@ -76,7 +76,7 @@ public:
         * \param endFilter The finishing callback.
         * \param data Data pointer for the callbacks.
         */
-       AUD_CallbackIIRFilterReader(AUD_IReader* reader, int in, int out,
+       AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out,
                                                                doFilterIIR doFilter,
                                                                endFilterIIR endFilter = 0,
                                                                void* data = 0);
index 1d2d99adc03fcf12bf4003a72cd226c414fa61eb..e452870281d27c2f79c125635a6112e85c6275ea 100644 (file)
@@ -33,7 +33,7 @@
 #include "AUD_DelayReader.h"
 #include "AUD_Space.h"
 
-AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
+AUD_DelayFactory::AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay) :
                AUD_EffectFactory(factory),
                m_delay(delay)
 {
@@ -44,7 +44,7 @@ float AUD_DelayFactory::getDelay() const
        return m_delay;
 }
 
-AUD_IReader* AUD_DelayFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DelayFactory::createReader()
 {
        return new AUD_DelayReader(getReader(), m_delay);
 }
index 1e67cd689909c5dd7b3e8fb93903f7533cb65e6e..5ab7f850d2f1700f87fb8d40fbb50ddc10e23e23 100644 (file)
@@ -55,14 +55,14 @@ public:
         * \param factory The input factory.
         * \param delay The desired delay in seconds.
         */
-       AUD_DelayFactory(AUD_IFactory* factory, float delay = 0);
+       AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay = 0);
 
        /**
         * Returns the delay in seconds.
         */
        float getDelay() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_DELAYFACTORY
index 374b876455d42f95a24aa238d21937564c5c689d..7d58b3dae4f33c82269e4e85c17df2c864b097fa 100644 (file)
 
 #include <cstring>
 
-AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
+AUD_DelayReader::AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay) :
                AUD_EffectReader(reader),
                m_delay(int(delay * reader->getSpecs().rate)),
-               m_remdelay(int(delay * reader->getSpecs().rate)),
-               m_empty(true)
+               m_remdelay(int(delay * reader->getSpecs().rate))
 {
 }
 
@@ -70,49 +69,30 @@ int AUD_DelayReader::getPosition() const
        return m_reader->getPosition() + m_delay;
 }
 
-void AUD_DelayReader::read(int & length, sample_t* & buffer)
+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(m_buffer.getSize() < length * samplesize)
-               {
-                       m_buffer.resize(length * samplesize);
-                       m_empty = false;
-               }
-
-               buffer = m_buffer.getBuffer();
-
                if(length > m_remdelay)
                {
-                       if(!m_empty)
-                               memset(buffer, 0, m_remdelay * samplesize);
+                       memset(buffer, 0, m_remdelay * samplesize);
 
                        int len = length - m_remdelay;
-                       sample_t* buf;
-                       m_reader->read(len, buf);
-
-                       memcpy(buffer + m_remdelay * specs.channels,
-                                  buf, len * samplesize);
+                       m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
 
-                       if(len < length-m_remdelay)
-                               length = m_remdelay + len;
+                       length = m_remdelay + len;
 
                        m_remdelay = 0;
-                       m_empty = false;
                }
                else
                {
-                       if(!m_empty)
-                       {
-                               memset(buffer, 0, length * samplesize);
-                               m_empty = true;
-                       }
+                       memset(buffer, 0, length * samplesize);
                        m_remdelay -= length;
                }
        }
        else
-               m_reader->read(length, buffer);
+               m_reader->read(length, eos, buffer);
 }
index 5f0af660bdf90bf5c36fa27d070b660754986119..128e589eede7171f28c0c1f8a8775dc4aa36fc05 100644 (file)
 #include "AUD_Buffer.h"
 
 /**
- * This class reads another reader and changes it's delay.
+ * This class reads another reader and delays it.
  */
 class AUD_DelayReader : public AUD_EffectReader
 {
 private:
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
        /**
         * The delay level.
         */
@@ -56,11 +51,6 @@ private:
         */
        int m_remdelay;
 
-       /**
-        * Whether the buffer is currently filled with zeros.
-        */
-       bool m_empty;
-
        // hide copy constructor and operator=
        AUD_DelayReader(const AUD_DelayReader&);
        AUD_DelayReader& operator=(const AUD_DelayReader&);
@@ -71,12 +61,12 @@ public:
         * \param reader The reader to read from.
         * \param delay The delay in seconds.
         */
-       AUD_DelayReader(AUD_IReader* reader, float delay);
+       AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay);
 
        virtual void seek(int position);
        virtual int getLength() const;
        virtual int getPosition() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_DELAYREADER
index 7a40f1f8c96b07def0543d307370adc0888109b1..e1e6ba504359c03adf82c789ffcb11582d92825a 100644 (file)
 #include "AUD_DoubleFactory.h"
 #include "AUD_DoubleReader.h"
 
-AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
                m_factory1(factory1), m_factory2(factory2)
 {
 }
 
-AUD_IReader* AUD_DoubleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DoubleFactory::createReader()
 {
-       AUD_IReader* reader1 = m_factory1->createReader();
-       AUD_IReader* reader2;
-
-       try
-       {
-               reader2 = m_factory2->createReader();
-       }
-       catch(AUD_Exception&)
-       {
-               delete reader1;
-               throw;
-       }
+       AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+       AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
 
        return new AUD_DoubleReader(reader1, reader2);
 }
index 52a299c7157dc79cdc4221d7e10240bff18f08d5..2db2257244c7c4aaa70fcb5d416894067c93fe9c 100644 (file)
@@ -36,7 +36,6 @@
 
 /**
  * This factory plays two other factories behind each other.
- * \note Readers from the underlying factories must have the same sample rate and channel count.
  */
 class AUD_DoubleFactory : public AUD_IFactory
 {
@@ -44,12 +43,12 @@ private:
        /**
         * First played factory.
         */
-       AUD_IFactory* m_factory1;
+       AUD_Reference<AUD_IFactory> m_factory1;
 
        /**
         * Second played factory.
         */
-       AUD_IFactory* m_factory2;
+       AUD_Reference<AUD_IFactory> m_factory2;
 
        // hide copy constructor and operator=
        AUD_DoubleFactory(const AUD_DoubleFactory&);
@@ -61,9 +60,9 @@ public:
         * \param factory1 The first input factory.
         * \param factory2 The second input factory.
         */
-       AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+       AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_DOUBLEFACTORY
index 113bed14ce3a0bd5b25354ed9f2dd07242bf2311..3b1d105954c122c4fad7d7a03c29acfae7a97b3b 100644 (file)
 
 #include <cstring>
 
-static const char* specs_error = "AUD_DoubleReader: Both readers have to have "
-                                                                "the same specs.";
-
-AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
-                                                                  AUD_IReader* reader2) :
+AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1,
+                                                                  AUD_Reference<AUD_IReader> reader2) :
                m_reader1(reader1), m_reader2(reader2), m_finished1(false)
 {
        AUD_Specs s1, s2;
        s1 = reader1->getSpecs();
        s2 = reader2->getSpecs();
-       if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
-       {
-               delete reader1;
-               delete reader2;
-               AUD_THROW(AUD_ERROR_SPECS, specs_error);
-       }
 }
 
 AUD_DoubleReader::~AUD_DoubleReader()
 {
-       delete m_reader1;
-       delete m_reader2;
 }
 
 bool AUD_DoubleReader::isSeekable() const
@@ -90,43 +79,36 @@ int AUD_DoubleReader::getPosition() const
 
 AUD_Specs AUD_DoubleReader::getSpecs() const
 {
-       return m_reader1->getSpecs();
+       return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
 }
 
-void AUD_DoubleReader::read(int & length, sample_t* & buffer)
+void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
 {
+       eos = false;
+
        if(!m_finished1)
        {
                int len = length;
-               m_reader1->read(len, buffer);
+
+               m_reader1->read(len, m_finished1, buffer);
 
                if(len < length)
                {
-                       AUD_Specs specs = m_reader1->getSpecs();
-                       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-                       if(m_buffer.getSize() < length * samplesize)
-                               m_buffer.resize(length * samplesize);
-
-                       sample_t* buf = buffer;
-                       buffer = m_buffer.getBuffer();
-
-                       memcpy(buffer, buf, len * samplesize);
-
-                       len = length - len;
-                       length -= len;
-                       m_reader2->read(len, buf);
-
-                       memcpy(buffer + length * specs.channels, buf,
-                                  len * samplesize);
-
-                       length += len;
-
-                       m_finished1 = true;
+                       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, buffer);
+               m_reader2->read(length, eos, buffer);
        }
 }
index 7b3b812ef80f8f794b66ae31bc8869bb322980ea..750868a94007a7d2c0d3c7fadc8aa9e1046d61a0 100644 (file)
 
 #include "AUD_IReader.h"
 #include "AUD_Buffer.h"
+#include "AUD_Reference.h"
 
 /**
- * This reader plays two readers with the same specs sequently.
+ * This reader plays two readers sequently.
  */
 class AUD_DoubleReader : public AUD_IReader
 {
@@ -44,35 +45,29 @@ private:
        /**
         * The first reader.
         */
-       AUD_IReader* m_reader1;
+       AUD_Reference<AUD_IReader> m_reader1;
 
        /**
         * The second reader.
         */
-       AUD_IReader* m_reader2;
+       AUD_Reference<AUD_IReader> m_reader2;
 
        /**
         * Whether we've reached the end of the first reader.
         */
        bool m_finished1;
 
-       /**
-        * The playback buffer for the intersecting part.
-        */
-       AUD_Buffer m_buffer;
-
        // hide copy constructor and operator=
        AUD_DoubleReader(const AUD_DoubleReader&);
        AUD_DoubleReader& operator=(const AUD_DoubleReader&);
 
 public:
        /**
-        * Creates a new ping pong reader.
+        * Creates a new double reader.
         * \param reader1 The first reader to read from.
         * \param reader2 The second reader to read from.
-        * \exception AUD_Exception Thrown if the specs from the readers differ.
         */
-       AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
+       AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
 
        /**
         * Destroys the reader.
@@ -84,7 +79,7 @@ public:
        virtual int getLength() const;
        virtual int getPosition() const;
        virtual AUD_Specs getSpecs() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_DOUBLEREADER
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
new file mode 100644 (file)
index 0000000..3018a2d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * ***** 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(AUD_Reference<AUD_IFactory> factory) :
+       AUD_EffectFactory(factory)
+{
+}
+
+AUD_Reference<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
+{
+       return new AUD_DynamicIIRFilterReader(getReader(), this);
+}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
new file mode 100644 (file)
index 0000000..56d56a9
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** 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
+#define AUD_DYNAMICIIRFILTERFACTORY
+
+#include "AUD_EffectFactory.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
+{
+public:
+       /**
+        * Creates a new Dynmic IIR filter factory.
+        * \param factory The input factory.
+        */
+       AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory);
+
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       /**
+        * 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_DYNAMICIIRFILTERFACTORY
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
new file mode 100644 (file)
index 0000000..ed9b2d3
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * ***** 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(AUD_Reference<AUD_IReader> reader,
+                                                                                                          AUD_Reference<AUD_DynamicIIRFilterFactory> factory) :
+       AUD_IIRFilterReader(reader, std::vector<float>(), std::vector<float>())
+{
+       sampleRateChanged(reader->getSpecs().rate);
+}
+
+void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
+{
+       std::vector<float> a, b;
+       m_factory->recalculateCoefficients(rate, b, a);
+       setCoefficients(b, a);
+}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
new file mode 100644 (file)
index 0000000..4278972
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * ***** 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
+#define AUD_DYNAMICIIRFILTERREADER
+
+#include "AUD_IIRFilterReader.h"
+#include "AUD_DynamicIIRFilterFactory.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.
+        */
+       AUD_Reference<AUD_DynamicIIRFilterFactory> m_factory;
+
+public:
+       AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
+                                                          AUD_Reference<AUD_DynamicIIRFilterFactory> factory);
+
+       virtual void sampleRateChanged(AUD_SampleRate rate);
+};
+
+#endif // AUD_DYNAMICIIRFILTERREADER
index a0d9256e6911c94381deae8c96b76bcfbaeaacc3..6173ffb5a979a5bfcd3d2fc9188dacbd532274c2 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_EffectFactory.h"
 #include "AUD_IReader.h"
 
-AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
+AUD_EffectFactory::AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory)
 {
        m_factory = factory;
 }
@@ -41,7 +41,7 @@ AUD_EffectFactory::~AUD_EffectFactory()
 {
 }
 
-AUD_IFactory* AUD_EffectFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_EffectFactory::getFactory() const
 {
        return m_factory;
 }
index a6a28eea5770e4eee5338fa27886d949125c47b8..72fdb3f0833b968baea1a1d00fdc69c36ee49d12 100644 (file)
@@ -49,7 +49,7 @@ protected:
        /**
         * If there is no reader it is created out of this factory.
         */
-       AUD_IFactory* m_factory;
+       AUD_Reference<AUD_IFactory> m_factory;
 
        /**
         * Returns the reader created out of the factory.
@@ -57,7 +57,7 @@ protected:
         * classes.
         * \return The reader created out of the factory.
         */
-       inline AUD_IReader* getReader() const
+       inline AUD_Reference<AUD_IReader> getReader() const
        {
                return m_factory->createReader();
        }
@@ -67,7 +67,7 @@ public:
         * Creates a new factory.
         * \param factory The input factory.
         */
-       AUD_EffectFactory(AUD_IFactory* factory);
+       AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory);
 
        /**
         * Destroys the factory.
@@ -78,7 +78,7 @@ public:
         * Returns the saved factory.
         * \return The factory or NULL if there has no factory been saved.
         */
-       AUD_IFactory* getFactory() const;
+       AUD_Reference<AUD_IFactory> getFactory() const;
 };
 
 #endif //AUD_EFFECTFACTORY
index 3ad9f67bfd6ce93794c5da8eb4c6299bddad0eb7..4d14af76438ac1ede4de8492890b2905ffaf078b 100644 (file)
 
 #include "AUD_EffectReader.h"
 
-AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
+AUD_EffectReader::AUD_EffectReader(AUD_Reference<AUD_IReader> reader)
 {
        m_reader = reader;
 }
 
 AUD_EffectReader::~AUD_EffectReader()
 {
-       delete m_reader;
 }
 
 bool AUD_EffectReader::isSeekable() const
@@ -66,7 +65,7 @@ AUD_Specs AUD_EffectReader::getSpecs() const
        return m_reader->getSpecs();
 }
 
-void AUD_EffectReader::read(int & length, sample_t* & buffer)
+void AUD_EffectReader::read(int& length, bool& eos, sample_t* buffer)
 {
-       m_reader->read(length, buffer);
+       m_reader->read(length, eos, buffer);
 }
index fb8066f36d8c0a300104dd6574d139ca05e7309c..c03abd1182891577e149c485ff58a15170593922 100644 (file)
@@ -33,6 +33,7 @@
 #define AUD_EFFECTREADER
 
 #include "AUD_IReader.h"
+#include "AUD_Reference.h"
 
 /**
  * This reader is a base class for all effect readers that take one other reader
@@ -49,14 +50,14 @@ protected:
        /**
         * The reader to read from.
         */
-       AUD_IReader* m_reader;
+       AUD_Reference<AUD_IReader> m_reader;
 
 public:
        /**
         * Creates a new effect reader.
         * \param reader The reader to read from.
         */
-       AUD_EffectReader(AUD_IReader* reader);
+       AUD_EffectReader(AUD_Reference<AUD_IReader> reader);
 
        /**
         * Destroys the reader.
@@ -68,7 +69,7 @@ public:
        virtual int getLength() const;
        virtual int getPosition() const;
        virtual AUD_Specs getSpecs() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_EFFECTREADER
index 069317d1c8b1a766ca49fdb57e356ebcdc74476a..80df7e9f8748e249c5fce9610c5bb32a97103b62 100644 (file)
@@ -42,7 +42,7 @@ struct EnvelopeParameters
        float arthreshold;
 };
 
-sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+sample_t AUD_EnvelopeFactory::envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
 {
        float in = fabs(reader->x(0));
        float out = reader->y(-1);
@@ -51,12 +51,12 @@ sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters*
        return (in > out ? param->attack : param->release) * (out - in) + in;
 }
 
-void endEnvelopeFilter(EnvelopeParameters* param)
+void AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
 {
        delete param;
 }
 
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack,
                                                                                 float release, float threshold,
                                                                                 float arthreshold) :
                AUD_EffectFactory(factory),
@@ -67,14 +67,14 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
 {
 }
 
-AUD_IReader* AUD_EnvelopeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
 {
-       AUD_IReader* reader = getReader();
+       AUD_Reference<AUD_IReader> reader = getReader();
 
        EnvelopeParameters* param = new EnvelopeParameters();
        param->arthreshold = m_arthreshold;
-       param->attack = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_attack));
-       param->release = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_release));
+       param->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 new AUD_CallbackIIRFilterReader(reader, 1, 2,
index 45ee811b6e040274f765f33a91ecd19ed9ef0dc4..a480a05d47801789a00640a8a056087dfe8af8c9 100644 (file)
@@ -33,6 +33,8 @@
 #define AUD_ENVELOPEFACTORY
 
 #include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
+struct EnvelopeParameters;
 
 /**
  * This factory creates an envelope follower reader.
@@ -73,10 +75,13 @@ public:
         * \param threshold The threshold value.
         * \param arthreshold The attack/release threshold value.
         */
-       AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
+       AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack, float release,
                                                float threshold, float arthreshold);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       static sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param);
+       static void endEnvelopeFilter(EnvelopeParameters* param);
 };
 
 #endif //AUD_ENVELOPEFACTORY
index d887e9e68d9cc69b65ac7e07a59c11c728bd866c..635873e0ee572eb8b80c094aecb1dee4060666a5 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_FaderFactory.h"
 #include "AUD_FaderReader.h"
 
-AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
+AUD_FaderFactory::AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory, AUD_FadeType type,
                                                                   float start, float length) :
                AUD_EffectFactory(factory),
                m_type(type),
@@ -56,7 +56,7 @@ float AUD_FaderFactory::getLength() const
        return m_length;
 }
 
-AUD_IReader* AUD_FaderFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FaderFactory::createReader()
 {
        return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
 }
index b85475bc5346dc710bd7c3a32e86f4dd24f053e4..d8314c77ed4c2a1ee1c4bbc1e5c9a5b8e14203c5 100644 (file)
@@ -69,7 +69,7 @@ public:
         * \param start The time where fading should start in seconds.
         * \param length How long fading should last in seconds.
         */
-       AUD_FaderFactory(AUD_IFactory* factory,
+       AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory,
                                          AUD_FadeType type = AUD_FADE_IN,
                                          float start = 0.0f, float length = 1.0f);
 
@@ -88,7 +88,7 @@ public:
         */
        float getLength() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_FADERFACTORY
index 6114bb486fce871784a94a0fe37d898ada54d70d..4a6050cf0f359984310b56df07f63b9d5f72aa67 100644 (file)
 
 #include <cstring>
 
-AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+AUD_FaderReader::AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
                                                                 float start,float length) :
                AUD_EffectReader(reader),
                m_type(type),
                m_start(start),
-               m_length(length),
-               m_empty(true)
+               m_length(length)
 {
 }
 
-void AUD_FaderReader::read(int & length, sample_t* & buffer)
+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, buffer);
+       m_reader->read(length, eos, buffer);
 
        if((position + length) / (float)specs.rate <= m_start)
        {
                if(m_type != AUD_FADE_OUT)
                {
-                       if(m_buffer.getSize() < length * samplesize)
-                       {
-                               m_buffer.resize(length * samplesize);
-                               m_empty = false;
-                       }
-
-                       buffer = m_buffer.getBuffer();
-
-                       if(!m_empty)
-                       {
-                               memset(buffer, 0, length * samplesize);
-                               m_empty = true;
-                       }
+                       memset(buffer, 0, length * samplesize);
                }
        }
        else if(position / (float)specs.rate >= m_start+m_length)
        {
                if(m_type == AUD_FADE_OUT)
                {
-                       if(m_buffer.getSize() < length * samplesize)
-                       {
-                               m_buffer.resize(length * samplesize);
-                               m_empty = false;
-                       }
-
-                       buffer = m_buffer.getBuffer();
-
-                       if(!m_empty)
-                       {
-                               memset(buffer, 0, length * samplesize);
-                               m_empty = true;
-                       }
+                       memset(buffer, 0, length * samplesize);
                }
        }
        else
        {
-               if(m_buffer.getSize() < length * samplesize)
-                       m_buffer.resize(length * samplesize);
-
-               sample_t* buf = m_buffer.getBuffer();
                float volume = 1.0f;
 
                for(int i = 0; i < length * specs.channels; i++)
@@ -111,10 +82,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
                                        volume = 1.0f - volume;
                        }
 
-                       buf[i] = buffer[i] * volume;
+                       buffer[i] = buffer[i] * volume;
                }
-
-               buffer = buf;
-               m_empty = false;
        }
 }
index fb927192b45ae310e91f1f17d41994d3f70d3dbd..e702ac0ec19be9c79792d5bcfd03bb1189fadc04 100644 (file)
@@ -58,16 +58,6 @@ private:
         */
        const float m_length;
 
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
-       /**
-        * Whether the buffer is empty.
-        */
-       bool m_empty;
-
        // hide copy constructor and operator=
        AUD_FaderReader(const AUD_FaderReader&);
        AUD_FaderReader& operator=(const AUD_FaderReader&);
@@ -79,10 +69,10 @@ public:
         * \param start The time where fading should start in seconds.
         * \param length How long fading should last in seconds.
         */
-       AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+       AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
                                        float start,float length);
 
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_FADERREADER
index 61008eea44e7162423630deeb83ec6f8801d913c..399ec5ca406d8bb3fcfb3bb1dc6f9345d9ff733d 100644 (file)
 #define M_PI 3.14159265358979323846
 #endif
 
-AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
+AUD_HighpassFactory::AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
                                                                                 float Q) :
-               AUD_EffectFactory(factory),
+               AUD_DynamicIIRFilterFactory(factory),
                m_frequency(frequency),
                m_Q(Q)
 {
 }
 
-AUD_IReader* AUD_HighpassFactory::createReader() const
+void AUD_HighpassFactory::recalculateCoefficients(AUD_SampleRate rate,
+                                                                                                 std::vector<float> &b,
+                                                                                                 std::vector<float> &a)
 {
-       AUD_IReader* reader = getReader();
-
-       // calculate coefficients
-       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float w0 = 2 * M_PI * m_frequency / rate;
        float alpha = sin(w0) / (2 * m_Q);
        float norm = 1 + alpha;
        float c = cos(w0);
-       std::vector<float> a, b;
        a.push_back(1);
        a.push_back(-2 * c / norm);
        a.push_back((1 - alpha) / norm);
        b.push_back((1 + c) / (2 * norm));
        b.push_back((-1 - c) / norm);
        b.push_back(b[0]);
-
-       return new AUD_IIRFilterReader(reader, b, a);
 }
index 48f4c1baefc4ccd7bc856f27e993a4449a042bd0..c135be27d770f0ac3753aec243e79a872d6c76d9 100644 (file)
 #ifndef AUD_HIGHPASSFACTORY
 #define AUD_HIGHPASSFACTORY
 
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
 
 /**
  * This factory creates a highpass filter reader.
  */
-class AUD_HighpassFactory : public AUD_EffectFactory
+class AUD_HighpassFactory : public AUD_DynamicIIRFilterFactory
 {
 private:
        /**
-        * The attack value in seconds.
+        * The cutoff frequency.
         */
        const float m_frequency;
 
@@ -61,9 +61,9 @@ public:
         * \param frequency The cutoff frequency.
         * \param Q The Q factor.
         */
-       AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+       AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
 
-       virtual AUD_IReader* createReader() const;
+       virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
 };
 
 #endif //AUD_HIGHPASSFACTORY
index ff90ce6273910bff479d59bcbbaf624cdce02c8c..f6ccda6f67e5f6f9a9c12e0d46c90a461ad3c4cd 100644 (file)
 #include "AUD_IIRFilterFactory.h"
 #include "AUD_IIRFilterReader.h"
 
-AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory,
                                                                                   std::vector<float> b,
                                                                                   std::vector<float> a) :
                AUD_EffectFactory(factory), m_a(a), m_b(b)
 {
 }
 
-AUD_IReader* AUD_IIRFilterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_IIRFilterFactory::createReader()
 {
        return new AUD_IIRFilterReader(getReader(), m_b, m_a);
 }
index d48ad453ee46c115fb679141d50afd3800f07f56..0e92ab1a568e88d712ee4c55d3b4b7d269cd6dbf 100644 (file)
@@ -63,10 +63,10 @@ public:
         * \param b The input filter coefficients.
         * \param a The output filter coefficients.
         */
-       AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
+       AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory, std::vector<float> b,
                                                 std::vector<float> a);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_IIRFILTERFACTORY
index 0d55421d2b4965312456f0ff06c35f0a43ce9542..1bfb9b97b62a2b4b2a79886d349523bd811f5d6a 100644 (file)
@@ -31,9 +31,9 @@
 
 #include "AUD_IIRFilterReader.h"
 
-AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
-                                                                                std::vector<float> b,
-                                                                                std::vector<float> a) :
+AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_Reference<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)
 {
        for(int i = 1; i < m_a.size(); i++)
@@ -54,3 +54,11 @@ sample_t AUD_IIRFilterReader::filter()
 
        return out;
 }
+
+void AUD_IIRFilterReader::setCoefficients(const std::vector<float>& b,
+                                                                                 const std::vector<float>& a)
+{
+       setLengths(m_b.size(), m_a.size());
+       m_a = a;
+       m_b = b;
+}
index af50b6f1cdc26a70adbac271467b455fe916dc72..41de67d4d27419de773ba8e73162bd0b81463aab 100644 (file)
@@ -63,10 +63,13 @@ public:
         * \param b The input filter coefficients.
         * \param a The output filter coefficients.
         */
-       AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
-                                               std::vector<float> a);
+       AUD_IIRFilterReader(AUD_Reference<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
index 62ea01bb76191e58c2147a08c10969faf12eb651..8d1dd14f3aed7601f2a370fb8cf15d8d9b4175a8 100644 (file)
@@ -33,7 +33,7 @@
 #include "AUD_LimiterReader.h"
 #include "AUD_Space.h"
 
-AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
+AUD_LimiterFactory::AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
                                                                           float start, float end) :
                AUD_EffectFactory(factory),
                m_start(start),
@@ -51,7 +51,7 @@ float AUD_LimiterFactory::getEnd() const
        return m_end;
 }
 
-AUD_IReader* AUD_LimiterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LimiterFactory::createReader()
 {
        return new AUD_LimiterReader(getReader(), m_start, m_end);
 }
index f93f4b3276c4d650e07e3fe683d415cd7a572371..c04bfe861b2752c7bea69493a7fa347a1f73256c 100644 (file)
@@ -62,7 +62,7 @@ public:
         * \param end The desired end time, a negative value signals that it should
         *            play to the end.
         */
-       AUD_LimiterFactory(AUD_IFactory* factory,
+       AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
                                           float start = 0, float end = -1);
 
        /**
@@ -75,7 +75,7 @@ public:
         */
        float getEnd() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_LIMITERFACTORY
index d67fbb4d0e52931c9e1aadf710d2b8a9669f44a5..dc31477d2eb21f66ca69a22506cc85286de5d69d 100644 (file)
 #include "AUD_LimiterReader.h"
 #include "AUD_Buffer.h"
 
-#include <iostream>
-
-AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
+AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader,
                                                                         float start, float end) :
                AUD_EffectReader(reader),
-               m_start(int(start * reader->getSpecs().rate)),
-               m_end(int(end * reader->getSpecs().rate))
+               m_start(start),
+               m_end(end)
 {
        if(m_start > 0)
        {
+               AUD_Specs specs = m_reader->getSpecs();
+               AUD_Specs specs2;
+
                if(m_reader->isSeekable())
-                       m_reader->seek(m_start);
+                       m_reader->seek(m_start * specs.rate);
                else
                {
                        // skip first m_start samples by reading them
                        int length = AUD_DEFAULT_BUFFER_SIZE;
-                       sample_t* buffer;
-                       for(int len = m_start;
-                               length == AUD_DEFAULT_BUFFER_SIZE;
-                               len -= AUD_DEFAULT_BUFFER_SIZE)
+                       AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+                       bool eos = false;
+                       for(int len = m_start * specs.rate;
+                               length > 0 && !eos;
+                               len -= length)
                        {
                                if(len < AUD_DEFAULT_BUFFER_SIZE)
                                        length = len;
-                               m_reader->read(length, buffer);
+
+                               m_reader->read(length, eos, buffer.getBuffer());
+
+                               specs2 = m_reader->getSpecs();
+                               if(specs2.rate != specs.rate)
+                               {
+                                       len = len * specs2.rate / specs.rate;
+                                       specs.rate = specs2.rate;
+                               }
+
+                               if(specs2.channels != specs.channels)
+                               {
+                                       specs = specs2;
+                                       buffer.assureSize(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+                               }
                        }
                }
        }
@@ -63,35 +79,71 @@ AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
 
 void AUD_LimiterReader::seek(int position)
 {
-       m_reader->seek(position + m_start);
+       m_reader->seek(position + m_start * m_reader->getSpecs().rate);
 }
 
 int AUD_LimiterReader::getLength() const
 {
        int len = m_reader->getLength();
-       if(len < 0 || (len > m_end && m_end >= 0))
-               len = m_end;
-       return len - m_start;
+       AUD_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 pos = m_reader->getPosition();
-       return AUD_MIN(pos, m_end) - m_start;
+       AUD_SampleRate rate = m_reader->getSpecs().rate;
+       return AUD_MIN(pos, m_end * rate) - m_start * rate;
 }
 
-void AUD_LimiterReader::read(int & length, sample_t* & buffer)
+void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
 {
+       eos = false;
        if(m_end >= 0)
        {
                int position = m_reader->getPosition();
-               if(position + length > m_end)
-                       length = m_end - position;
+               AUD_SampleRate rate = m_reader->getSpecs().rate;
+
+               if(position + length > m_end * rate)
+               {
+                       length = m_end * rate - position;
+                       eos = true;
+               }
+
+               if(position < m_start * rate)
+               {
+                       int len2 = length;
+                       for(int len = m_start * rate - position;
+                               len2 == length && !eos;
+                               len -= length)
+                       {
+                               if(len < length)
+                                       len2 = len;
+
+                               m_reader->read(len2, eos, buffer);
+                               position += len2;
+                       }
+
+                       if(position < m_start * rate)
+                       {
+                               length = 0;
+                               return;
+                       }
+               }
+
                if(length < 0)
                {
                        length = 0;
                        return;
                }
        }
-       m_reader->read(length, buffer);
+       if(eos)
+       {
+               m_reader->read(length, eos, buffer);
+               eos = true;
+       }
+       else
+               m_reader->read(length, eos, buffer);
 }
index 4375ed9e10dc7f4ef46dfe8e857c80ed40f0af7d..9cddd4d57ec1476ea0c55da63e4eac05e240c5a1 100644 (file)
@@ -35,7 +35,7 @@
 #include "AUD_EffectReader.h"
 
 /**
- * This reader limits another reader in start and end sample.
+ * This reader limits another reader in start and end times.
  */
 class AUD_LimiterReader : public AUD_EffectReader
 {
@@ -43,12 +43,12 @@ private:
        /**
         * The start sample: inclusive.
         */
-       const int m_start;
+       const float m_start;
 
        /**
         * The end sample: exlusive.
         */
-       const int m_end;
+       const float m_end;
 
        // hide copy constructor and operator=
        AUD_LimiterReader(const AUD_LimiterReader&);
@@ -58,16 +58,16 @@ public:
        /**
         * Creates a new limiter reader.
         * \param reader The reader to read from.
-        * \param start The desired start sample (inclusive).
-        * \param end The desired end sample (exklusive), a negative value signals
-        *            that it should play to the end.
+        * \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(AUD_IReader* reader, float start = 0, float end = -1);
+       AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, float start = 0, float end = -1);
 
        virtual void seek(int position);
        virtual int getLength() const;
        virtual int getPosition() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_LIMITERREADER
index 49d3481757fb89b4e8f5197d282aba0b4aa0b64b..fd39ac901c1f84ac828237a1a222b66e41e31ca7 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_LoopFactory.h"
 #include "AUD_LoopReader.h"
 
-AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
+AUD_LoopFactory::AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop) :
                AUD_EffectFactory(factory),
                m_loop(loop)
 {
@@ -43,7 +43,7 @@ int AUD_LoopFactory::getLoop() const
        return m_loop;
 }
 
-AUD_IReader* AUD_LoopFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LoopFactory::createReader()
 {
        return new AUD_LoopReader(getReader(), m_loop);
 }
index dfbbbe4fd20d155a25f1b6d53bedc308ce217ebb..03c00dc40ceeda788c260dccee0ba7ebd78af57b 100644 (file)
@@ -57,14 +57,14 @@ public:
         * \param loop The desired loop count, negative values result in endless
         *        looping.
         */
-       AUD_LoopFactory(AUD_IFactory* factory, int loop = -1);
+       AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop = -1);
 
        /**
         * Returns the loop count.
         */
        int getLoop() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_LOOPFACTORY
index b2e8e97a60295cc679d5cbfdbe0033ff17919580..de67a445ab2d29a52b0a8e7d00dfcdaf8a96261b 100644 (file)
@@ -34,7 +34,7 @@
 
 #include <cstring>
 
-AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
+AUD_LoopReader::AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop) :
                AUD_EffectReader(reader), m_count(loop), m_left(loop)
 {
 }
@@ -68,29 +68,20 @@ int AUD_LoopReader::getPosition() const
        return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
 }
 
-void AUD_LoopReader::read(int & length, sample_t* & buffer)
+void AUD_LoopReader::read(int& length, bool& eos, sample_t* buffer)
 {
-       AUD_Specs specs = m_reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
+       const AUD_Specs specs = m_reader->getSpecs();
 
        int len = length;
 
-       m_reader->read(len, buffer);
+       m_reader->read(length, eos, buffer);
 
-       if(len < length && m_left)
+       if(length < len && eos && m_left)
        {
-               int pos = 0;
-
-               if(m_buffer.getSize() < length * samplesize)
-                       m_buffer.resize(length * samplesize);
-
-               sample_t* buf = m_buffer.getBuffer();
-
-               memcpy(buf + pos * specs.channels, buffer, len * samplesize);
-
-               pos += len;
+               int pos = length;
+               length = len;
 
-               while(pos < length && m_left)
+               while(pos < length && eos && m_left)
                {
                        if(m_left > 0)
                                m_left--;
@@ -98,20 +89,15 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
                        m_reader->seek(0);
 
                        len = length - pos;
-                       m_reader->read(len, buffer);
+                       m_reader->read(len, eos, buffer + pos * specs.channels);
 
                        // prevent endless loop
                        if(!len)
                                break;
 
-                       memcpy(buf + pos * specs.channels, buffer, len * samplesize);
-
                        pos += len;
                }
 
                length = pos;
-               buffer = buf;
        }
-       else
-               length = len;
 }
index 45017901c568cf941a8785037e7eda72ac2b0d81..5ccf7e543a0c7d8d543c249081ad7e933870bb19 100644 (file)
 class AUD_LoopReader : public AUD_EffectReader
 {
 private:
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
        /**
         * The loop count.
         */
@@ -68,12 +63,12 @@ public:
         * \param loop The desired loop count, negative values result in endless
         *        looping.
         */
-       AUD_LoopReader(AUD_IReader* reader, int loop);
+       AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop);
 
        virtual void seek(int position);
        virtual int getLength() const;
        virtual int getPosition() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_LOOPREADER
index d24a04b5a94d77a92483381d66039136c8d7a2f9..3ef25c3c16ed269070007ddc3978798c7401be5d 100644 (file)
 #define M_PI 3.14159265358979323846
 #endif
 
-AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
+AUD_LowpassFactory::AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
                                                                           float Q) :
-               AUD_EffectFactory(factory),
+               AUD_DynamicIIRFilterFactory(factory),
                m_frequency(frequency),
                m_Q(Q)
 {
 }
 
-AUD_IReader* AUD_LowpassFactory::createReader() const
+void AUD_LowpassFactory::recalculateCoefficients(AUD_SampleRate rate,
+                                                                                                std::vector<float> &b,
+                                                                                                std::vector<float> &a)
 {
-       AUD_IReader* reader = getReader();
-
-       // calculate coefficients
-       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float w0 = 2 * M_PI * m_frequency / rate;
        float alpha = sin(w0) / (2 * m_Q);
        float norm = 1 + alpha;
        float c = cos(w0);
-       std::vector<float> a, b;
        a.push_back(1);
        a.push_back(-2 * c / norm);
        a.push_back((1 - alpha) / norm);
        b.push_back((1 - c) / (2 * norm));
        b.push_back((1 - c) / norm);
        b.push_back(b[0]);
-
-       return new AUD_IIRFilterReader(reader, b, a);
 }
index d60c0bd22d182c12d46a640f1929a2e7f025db07..644d25ec73d12fc9e3cc91ec4eba275acb8eb3de 100644 (file)
 #ifndef AUD_LOWPASSFACTORY
 #define AUD_LOWPASSFACTORY
 
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
 
 /**
  * This factory creates a lowpass filter reader.
  */
-class AUD_LowpassFactory : public AUD_EffectFactory
+class AUD_LowpassFactory : public AUD_DynamicIIRFilterFactory
 {
 private:
        /**
-        * The attack value in seconds.
+        * The cutoff frequency.
         */
        const float m_frequency;
 
@@ -61,9 +61,9 @@ public:
         * \param frequency The cutoff frequency.
         * \param Q The Q factor.
         */
-       AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+       AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
 
-       virtual AUD_IReader* createReader() const;
+       virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
 };
 
 #endif //AUD_LOWPASSFACTORY
index fa14055594358c2cd4cd10a7f600dc032f683b0a..e5f2193ea565116ee62628b38f0be1c721a11d50 100644 (file)
 #include "AUD_DoubleReader.h"
 #include "AUD_ReverseFactory.h"
 
-AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
+AUD_PingPongFactory::AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory) :
                AUD_EffectFactory(factory)
 {
 }
 
-AUD_IReader* AUD_PingPongFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PingPongFactory::createReader()
 {
-       AUD_IReader* reader = getReader();
-       AUD_IReader* reader2;
+       AUD_Reference<AUD_IReader> reader = getReader();
        AUD_ReverseFactory factory(m_factory);
-
-       try
-       {
-               reader2 = factory.createReader();
-       }
-       catch(AUD_Exception&)
-       {
-               delete reader;
-               throw;
-       }
+       AUD_Reference<AUD_IReader> reader2 = factory.createReader();
 
        return new AUD_DoubleReader(reader, reader2);
 }
index 4ae0c494eb7104b9290ae52d75f76c975bdc7bc1..b023501d45bde9810627fe3eb76efe107ccb1816 100644 (file)
@@ -36,7 +36,7 @@
 
 /**
  * This factory plays another factory first normal, then reversed.
- * \note Readers from the underlying factory must be from the buffer type.
+ * \note Readers from the underlying factory must be reversable with seeking.
  */
 class AUD_PingPongFactory : public AUD_EffectFactory
 {
@@ -50,9 +50,9 @@ public:
         * Creates a new ping pong factory.
         * \param factory The input factory.
         */
-       AUD_PingPongFactory(AUD_IFactory* factory);
+       AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_PINGPONGFACTORY
index b4ae8582cafaa27bed3894351eee0cebff9be619..e52028754e9be51f390c1accccb23bee30239096 100644 (file)
 #include "AUD_PitchReader.h"
 #include "AUD_Space.h"
 
-AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
+AUD_PitchFactory::AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch) :
                AUD_EffectFactory(factory),
                m_pitch(pitch)
 {
 }
 
-AUD_IReader* AUD_PitchFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PitchFactory::createReader()
 {
        return new AUD_PitchReader(getReader(), m_pitch);
 }
index 8fa5be9293f6b82bd483c157d74faab1afb47bde..2642d41af89d89b5d44298e60f839f92b88a302d 100644 (file)
@@ -55,9 +55,9 @@ public:
         * \param factory The input factory.
         * \param pitch The desired pitch.
         */
-       AUD_PitchFactory(AUD_IFactory* factory, float pitch);
+       AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_PITCHFACTORY
index e2e89e2c45731e01d201476963b766b127ec857b..81dd6e4355cbc366da0c2b60665c4f6d8e2b880d 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "AUD_PitchReader.h"
 
-AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
+AUD_PitchReader::AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch) :
                AUD_EffectReader(reader), m_pitch(pitch)
 {
 }
@@ -39,6 +39,16 @@ AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
 AUD_Specs AUD_PitchReader::getSpecs() const
 {
        AUD_Specs specs = m_reader->getSpecs();
-       specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
+       specs.rate *= m_pitch;
        return specs;
 }
+
+float AUD_PitchReader::getPitch() const
+{
+       return m_pitch;
+}
+
+void AUD_PitchReader::setPitch(float pitch)
+{
+       m_pitch = pitch;
+}
index 120cebc58beb42b2a2485f0be260345a5b5a0878..ed6adbf02fb447f2fc6da8914638830a65475724 100644 (file)
@@ -43,7 +43,7 @@ private:
        /**
         * The pitch level.
         */
-       const float m_pitch;
+       float m_pitch;
 
        // hide copy constructor and operator=
        AUD_PitchReader(const AUD_PitchReader&);
@@ -53,11 +53,23 @@ public:
        /**
         * Creates a new pitch reader.
         * \param reader The reader to read from.
-        * \param pitch The size of the buffer.
+        * \param pitch The pitch value.
         */
-       AUD_PitchReader(AUD_IReader* reader, float pitch);
+       AUD_PitchReader(AUD_Reference<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
index 609d827cce49e51e8bafb16791367e74a3e0f4e9..cbb676a9a32b6ed6dbf22b9ec401b686d2e8e59a 100644 (file)
 
 #include <cmath>
 
-sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_RectifyFactory::rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
 {
        return fabs(reader->x(0));
 }
 
-AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
+AUD_RectifyFactory::AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory) :
                AUD_EffectFactory(factory)
 {
 }
 
-AUD_IReader* AUD_RectifyFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_RectifyFactory::createReader()
 {
        return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
 }
index c3529c7beef6773d21a3ef2fecb439bf347fb7e3..16b44469c056a949e47c68cb30560339a519ab24 100644 (file)
@@ -33,6 +33,7 @@
 #define AUD_RECTIFYFACTORY
 
 #include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
 
 /**
  * This factory rectifies another factory.
@@ -49,9 +50,11 @@ public:
         * Creates a new rectify factory.
         * \param factory The input factory.
         */
-       AUD_RectifyFactory(AUD_IFactory* factory);
+       AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       static sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
 };
 
 #endif //AUD_RECTIFYFACTORY
index 22b12e3142008b1dddde233d46e7e81c03039ff9..060a618dd6802825c1b35607175d2b92fa56d915 100644 (file)
 #include "AUD_ReverseReader.h"
 #include "AUD_Space.h"
 
-AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
+AUD_ReverseFactory::AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory) :
                AUD_EffectFactory(factory)
 {
 }
 
-AUD_IReader* AUD_ReverseFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ReverseFactory::createReader()
 {
        return new AUD_ReverseReader(getReader());
 }
index 7b20546302e3efcc3de19a2364bba726cca9bd90..f43d37d8f465d6d2a6081c6dcf43fb6049d5d20f 100644 (file)
@@ -36,7 +36,7 @@
 
 /**
  * This factory reads another factory reverted.
- * \note Readers from the underlying factory must be from the buffer type.
+ * \note Readers from the underlying factory must be seekable.
  */
 class AUD_ReverseFactory : public AUD_EffectFactory
 {
@@ -50,9 +50,9 @@ public:
         * Creates a new reverse factory.
         * \param factory The input factory.
         */
-       AUD_ReverseFactory(AUD_IFactory* factory);
+       AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_REVERSEFACTORY
index a4a03936c76743f1fdef172cf0036e18b736aa5a..73f6830f3fa6a495e56b811d7515383adc3ba66c 100644 (file)
@@ -36,7 +36,7 @@
 static const char* props_error = "AUD_ReverseReader: The reader has to be "
                                                                 "seekable and a finite length.";
 
-AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
+AUD_ReverseReader::AUD_ReverseReader(AUD_Reference<AUD_IReader> reader) :
                AUD_EffectReader(reader),
                m_length(reader->getLength()),
                m_position(0)
@@ -60,7 +60,7 @@ int AUD_ReverseReader::getPosition() const
        return m_position;
 }
 
-void AUD_ReverseReader::read(int & length, sample_t* & buffer)
+void AUD_ReverseReader::read(int& length, bool& eos, sample_t* buffer)
 {
        // first correct the length
        if(m_position + length > m_length)
@@ -69,39 +69,39 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
        if(length <= 0)
        {
                length = 0;
+               eos = true;
                return;
        }
 
-       AUD_Specs specs = getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
+       const AUD_Specs specs = getSpecs();
+       const int samplesize = AUD_SAMPLE_SIZE(specs);
 
-       // resize buffer if needed
-       if(m_buffer.getSize() < length * samplesize)
-               m_buffer.resize(length * samplesize);
+       sample_t temp[AUD_CHANNEL_MAX];
 
-       buffer = m_buffer.getBuffer();
-
-       sample_t* buf;
        int len = length;
 
        // read from reader
        m_reader->seek(m_length - m_position - len);
-       m_reader->read(len, buf);
+       m_reader->read(len, eos, buffer);
 
        // set null if reader didn't give enough data
        if(len < length)
-       {
                memset(buffer, 0, (length - len) * samplesize);
-               buffer += (length - len) * specs.channels;
-       }
 
        // copy the samples reverted
-       for(int i = 0; i < len; i++)
+       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,
-                          buf + (len - 1 - i) * specs.channels,
+                          temp,
                           samplesize);
+       }
 
        m_position += length;
-
-       buffer = m_buffer.getBuffer();
+       eos = false;
 }
index e12f2b2119191ab3bdcf09bdba1ecae85e13557b..197d10dfe001fecebf10f1d62f3747e6bca38f43 100644 (file)
@@ -37,7 +37,7 @@
 
 /**
  * This class reads another reader from back to front.
- * \note The underlying reader must be a buffer.
+ * \note The underlying reader must be seekable.
  */
 class AUD_ReverseReader : public AUD_EffectReader
 {
@@ -52,11 +52,6 @@ private:
         */
        int m_position;
 
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
        // hide copy constructor and operator=
        AUD_ReverseReader(const AUD_ReverseReader&);
        AUD_ReverseReader& operator=(const AUD_ReverseReader&);
@@ -68,12 +63,12 @@ public:
         * \exception AUD_Exception Thrown if the reader specified has an
         *            undeterminable/infinite length or is not seekable.
         */
-       AUD_ReverseReader(AUD_IReader* reader);
+       AUD_ReverseReader(AUD_Reference<AUD_IReader> reader);
 
        virtual void seek(int position);
        virtual int getLength() const;
        virtual int getPosition() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_REVERSEREADER
index a075773d2cba1d4c4a27a833a9a3de7a255757b9..226085a18146bdafb8362360abdf9bb37e1c5a1e 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_SquareFactory.h"
 #include "AUD_CallbackIIRFilterReader.h"
 
-sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
+sample_t AUD_SquareFactory::squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
 {
        float in = reader->x(0);
        if(in >= *threshold)
@@ -43,12 +43,12 @@ sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
                return 0;
 }
 
-void endSquareFilter(float* threshold)
+void AUD_SquareFactory::endSquareFilter(float* threshold)
 {
        delete threshold;
 }
 
-AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
+AUD_SquareFactory::AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold) :
                AUD_EffectFactory(factory),
                m_threshold(threshold)
 {
@@ -59,7 +59,7 @@ float AUD_SquareFactory::getThreshold() const
        return m_threshold;
 }
 
-AUD_IReader* AUD_SquareFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SquareFactory::createReader()
 {
        return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
                                                                                   (doFilterIIR) squareFilter,
index 8060e98e2819f1ffd417926b3a630880b2965753..21284361ccaef796a69a5ae0c0e13d3cfb4cd13c 100644 (file)
@@ -33,6 +33,7 @@
 #define AUD_SQUAREFACTORY
 
 #include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
 
 /**
  * This factory Transforms any signal to a square signal.
@@ -55,14 +56,17 @@ public:
         * \param factory The input factory.
         * \param threshold The threshold.
         */
-       AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f);
+       AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold = 0.0f);
 
        /**
         * Returns the threshold.
         */
        float getThreshold() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       static sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold);
+       static void endSquareFilter(float* threshold);
 };
 
 #endif //AUD_SQUAREFACTORY
index 6d8368d6e3527dd11870d1a5f04f0af2e09a673c..befcc30360f38f27cff205b64624cff2b3732b06 100644 (file)
 #include "AUD_SumFactory.h"
 #include "AUD_IIRFilterReader.h"
 
-AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
+AUD_SumFactory::AUD_SumFactory(AUD_Reference<AUD_IFactory> factory) :
                AUD_EffectFactory(factory)
 {
 }
 
-AUD_IReader* AUD_SumFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SumFactory::createReader()
 {
        std::vector<float> a, b;
        a.push_back(1);
index ed19a0f258a6075ee1665955986246d08a0d9417..cdb4caf6e496e7a4e6c1f189f797c08ea8e7fbc0 100644 (file)
@@ -49,9 +49,9 @@ public:
         * Creates a new sum factory.
         * \param factory The input factory.
         */
-       AUD_SumFactory(AUD_IFactory* factory);
+       AUD_SumFactory(AUD_Reference<AUD_IFactory> factory);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_SUMFACTORY
index c13a0d0dd9532e369a64c1345d35148f0c543608..d514bfd8fca21d30ea69c4e4435dceab14ffd606 100644 (file)
 #include "AUD_SuperposeFactory.h"
 #include "AUD_SuperposeReader.h"
 
-AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
                m_factory1(factory1), m_factory2(factory2)
 {
 }
 
-AUD_IReader* AUD_SuperposeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SuperposeFactory::createReader()
 {
-       AUD_IReader* reader1 = m_factory1->createReader();
-       AUD_IReader* reader2;
-       try
-       {
-               reader2 = m_factory2->createReader();
-       }
-       catch(AUD_Exception&)
-       {
-               delete reader1;
-               throw;
-       }
+       AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+       AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
 
        return new AUD_SuperposeReader(reader1, reader2);
 }
index 32232012e4e3a0aea6227f5f6c24f2cbdd1a97ec..b12da62b49780c94b3cb9e1e529970479d61d921 100644 (file)
@@ -35,8 +35,9 @@
 #include "AUD_IFactory.h"
 
 /**
- * This factory plays two other factories behind each other.
- * \note Readers from the underlying factories must have the same sample rate and channel count.
+ * 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
 {
@@ -44,12 +45,12 @@ private:
        /**
         * First played factory.
         */
-       AUD_IFactory* m_factory1;
+       AUD_Reference<AUD_IFactory> m_factory1;
 
        /**
         * Second played factory.
         */
-       AUD_IFactory* m_factory2;
+       AUD_Reference<AUD_IFactory> m_factory2;
 
        // hide copy constructor and operator=
        AUD_SuperposeFactory(const AUD_SuperposeFactory&);
@@ -61,9 +62,9 @@ public:
         * \param factory1 The first input factory.
         * \param factory2 The second input factory.
         */
-       AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+       AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_SUPERPOSEFACTORY
index e64cf79188e09998ad23194e817c22e4e6311970..c07b7a9febfb9f1b706e0abd2f11e3c434b9e6c5 100644 (file)
 static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
                                                                 "have the same specs.";
 
-AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2) :
        m_reader1(reader1), m_reader2(reader2)
 {
-       try
-       {
-               AUD_Specs s1, s2;
-               s1 = reader1->getSpecs();
-               s2 = reader2->getSpecs();
-               if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
-                       AUD_THROW(AUD_ERROR_SPECS, specs_error);
-       }
-       catch(AUD_Exception&)
-       {
-               delete reader1;
-               delete reader2;
-
-               throw;
-       }
 }
 
 AUD_SuperposeReader::~AUD_SuperposeReader()
 {
-       delete m_reader1;
-       delete m_reader2;
 }
 
 bool AUD_SuperposeReader::isSeekable() const
@@ -94,28 +77,31 @@ AUD_Specs AUD_SuperposeReader::getSpecs() const
        return m_reader1->getSpecs();
 }
 
-void AUD_SuperposeReader::read(int & length, sample_t* & buffer)
+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);
 
-       if(m_buffer.getSize() < length * samplesize)
-               m_buffer.resize(length * samplesize);
-       buffer = m_buffer.getBuffer();
+       m_buffer.assureSize(length * samplesize);
 
        int len1 = length;
-       sample_t* buf;
-       m_reader1->read(len1, buf);
-       memcpy(buffer, buf, len1 * samplesize);
+       m_reader1->read(len1, eos, buffer);
 
        if(len1 < length)
                memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
 
        int len2 = length;
-       m_reader2->read(len2, buf);
+       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;
 }
index b256aade7ba7236a2dfb696a12c9e756287cd48f..07b4b105835854c312b3aebfe9f188a983842544 100644 (file)
 
 #include "AUD_IReader.h"
 #include "AUD_Buffer.h"
+#include "AUD_Reference.h"
 
 /**
- * This reader plays two readers with the same specs sequently.
+ * This reader plays two readers with the same specs in parallel.
  */
 class AUD_SuperposeReader : public AUD_IReader
 {
@@ -44,15 +45,15 @@ private:
        /**
         * The first reader.
         */
-       AUD_IReader* m_reader1;
+       AUD_Reference<AUD_IReader> m_reader1;
 
        /**
         * The second reader.
         */
-       AUD_IReader* m_reader2;
+       AUD_Reference<AUD_IReader> m_reader2;
 
        /**
-        * The playback buffer for the intersecting part.
+        * Buffer used for mixing.
         */
        AUD_Buffer m_buffer;
 
@@ -67,7 +68,7 @@ public:
         * \param reader2 The second reader to read from.
         * \exception AUD_Exception Thrown if the specs from the readers differ.
         */
-       AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+       AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
 
        /**
         * Destroys the reader.
@@ -79,7 +80,7 @@ public:
        virtual int getLength() const;
        virtual int getPosition() const;
        virtual AUD_Specs getSpecs() const;
-       virtual void read(int & length, sample_t* & buffer);
+       virtual void read(int& length, bool& eos, sample_t* buffer);
 };
 
 #endif //AUD_SUPERPOSEREADER
index 166fbf615122664f304e9e9b9846576b92db1329..17cefd4f3c3bc8ffac0c013563e3ffdf4d0dd23f 100644 (file)
@@ -32,7 +32,7 @@
 #include "AUD_VolumeFactory.h"
 #include "AUD_IIRFilterReader.h"
 
-AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
+AUD_VolumeFactory::AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume) :
                AUD_EffectFactory(factory),
                m_volume(volume)
 {
@@ -43,7 +43,7 @@ float AUD_VolumeFactory::getVolume() const
        return m_volume;
 }
 
-AUD_IReader* AUD_VolumeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_VolumeFactory::createReader()
 {
        std::vector<float> a, b;
        a.push_back(1);
index fa40ca110826125a034430bf31e6dbff1611df6e..0ca0102b7900bc019a38bf7fb5eb556923a9a270 100644 (file)
@@ -57,14 +57,15 @@ public:
         * \param factory The input factory.
         * \param volume The desired volume.
         */
-       AUD_VolumeFactory(AUD_IFactory* factory, float volume);
+       AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume);
 
        /**
         * Returns the volume.
+        * \return The current volume.
         */
        float getVolume() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_VOLUMEFACTORY
index 71e7b7677e888a7ae35d52b1a3223ef050526ed4..d5b365fa62f5d36e2bfec0885f513c3d2fc395b3 100644 (file)
 #include <unistd.h>
 #endif
 
-#define AUD_OPENAL_CYCLE_BUFFERS 3
+/*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.";
+
+AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<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());
+                       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()
+{
+       if(m_status)
+       {
+               m_device->lock();
+
+               if(m_status == AUD_STATUS_PLAYING)
+               {
+                       m_device->m_playingSounds.remove(this);
+                       m_device->m_pausedSounds.push_back(this);
+
+                       alSourcePause(m_source);
+
+                       m_status = AUD_STATUS_PAUSED;
+                       m_device->unlock();
+
+                       return true;
+               }
+
+               m_device->unlock();
+       }
+
+       return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
+{
+       if(m_status)
+       {
+               m_device->lock();
+
+               if(m_status == AUD_STATUS_PAUSED)
+               {
+                       m_device->m_pausedSounds.remove(this);
+                       m_device->m_playingSounds.push_back(this);
+
+                       m_device->start();
+                       m_status = AUD_STATUS_PLAYING;
+                       m_device->unlock();
+                       return true;
+               }
+
+               m_device->unlock();
+       }
+
+       return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       // AUD_XXX Create a reference of our own object so that it doesn't get
+       // deleted before the end of this function
+       AUD_Reference<AUD_OpenALHandle> This = this;
+
+       if(m_status == AUD_STATUS_PLAYING)
+               m_device->m_playingSounds.remove(This);
+       else
+               m_device->m_pausedSounds.remove(This);
+
+       m_device->unlock();
+
+       alDeleteSources(1, &m_source);
+       if(!m_isBuffered)
+               alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+
+       m_status = AUD_STATUS_INVALID;
+       return true;
+}
+
+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;
+
+       m_device->lock();
+
+       m_keep = keep;
+
+       m_device->unlock();
+
+       return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       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);
+
+               if(info != AL_PLAYING)
+               {
+                       if(info == AL_PAUSED)
+                               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());
+                                       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);
+               }
+       }
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
+{
+       if(!m_status)
+               return 0.0f;
+
+       m_device->lock();
+
+       float position = 0.0f;
+
+       alGetSourcef(m_source, AL_SEC_OFFSET, &position);
+
+       if(!m_isBuffered)
+       {
+               AUD_Specs specs = m_reader->getSpecs();
+               position += (m_reader->getPosition() - m_device->m_buffersize *
+                                        CYCLE_BUFFERS) / (float)specs.rate;
+       }
+
+       m_device->unlock();
+
+       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 result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_GAIN, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_GAIN, volume);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_PITCH, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_PITCH, pitch);
+
+       m_device->unlock();
+
+       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;
+       m_loopcount = count;
+       return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       m_stop = callback;
+       m_stop_data = data;
+
+       m_device->unlock();
+
+       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 result;
+
+       m_device->lock();
+
+       ALfloat p[3];
+       alGetSourcefv(m_source, AL_POSITION, p);
+
+       m_device->unlock();
+
+       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;
+
+       m_device->lock();
+
+       alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+
+       m_device->unlock();
+
+       return true;
+}
+
+AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
+{
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       ALfloat v[3];
+       alGetSourcefv(m_source, AL_VELOCITY, v);
+
+       m_device->unlock();
+
+       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;
+
+       m_device->lock();
+
+       alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+
+       m_device->unlock();
+
+       return true;
+}
+
+AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
+{
+       return m_orientation;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
+{
+       if(!m_status)
+               return false;
+
+       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;
+       m_device->lock();
+
+       alSourcefv(m_source, AL_DIRECTION, direction);
+
+       m_device->unlock();
+
+       m_orientation = orientation;
+
+       return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
+{
+       int result;
+
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_MAX_GAIN, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_MAX_GAIN, volume);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_MIN_GAIN, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_MIN_GAIN, volume);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_MAX_DISTANCE, distance);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
 
-/// Saves the data for playback.
-struct AUD_OpenALHandle : AUD_Handle
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
 {
-       /// Whether it's a buffered or a streamed source.
-       bool isBuffered;
+       float result = std::numeric_limits<float>::quiet_NaN();
 
-       /// The reader source.
-       AUD_IReader* reader;
+       if(!m_status)
+               return result;
 
-       /// Whether to keep the source if end of it is reached.
-       bool keep;
+       m_device->lock();
 
-       /// OpenAL sample format.
-       ALenum format;
+       alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
 
-       /// OpenAL source.
-       ALuint source;
+       m_device->unlock();
 
-       /// OpenAL buffers.
-       ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+       return result;
+}
 
-       /// The first buffer to be read next.
-       int current;
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
+{
+       if(!m_status)
+               return false;
 
-       /// Whether the stream doesn't return any more data.
-       bool data_end;
+       m_device->lock();
 
-       /// The loop count of the source.
-       int loopcount;
+       alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
 
-       /// The stop callback.
-       stopCallback stop;
+       m_device->unlock();
 
-       /// Stop callback data.
-       void* stop_data;
-};
+       return true;
+}
 
-struct AUD_OpenALBufferedFactory
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
 {
-       /// The factory.
-       AUD_IFactory* factory;
+       float result = std::numeric_limits<float>::quiet_NaN();
 
-       /// The OpenAL buffer.
-       ALuint buffer;
-};
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
+
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+
+       m_device->unlock();
+
+       return result;
+}
 
-typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
-typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
+{
+       if(!m_status)
+               return false;
+
+       m_device->lock();
+
+       alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+
+       m_device->unlock();
+
+       return true;
+}
 
 /******************************************************************************/
 /**************************** Threading Code **********************************/
@@ -130,16 +801,15 @@ void AUD_OpenALDevice::start(bool join)
 
 void AUD_OpenALDevice::updateStreams()
 {
-       AUD_OpenALHandle* sound;
+       AUD_Reference<AUD_OpenALHandle> sound;
 
        int length;
-       sample_t* buffer;
 
        ALint info;
        AUD_DeviceSpecs specs = m_specs;
        ALCenum cerr;
-       std::list<AUD_OpenALHandle*> stopSounds;
-       std::list<AUD_OpenALHandle*> pauseSounds;
+       std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds;
+       std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds;
        AUD_HandleIterator it;
 
        while(1)
@@ -151,83 +821,86 @@ void AUD_OpenALDevice::updateStreams()
                if(cerr == ALC_NO_ERROR)
                {
                        // for all sounds
-                       for(it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
+                       for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
                        {
                                sound = *it;
 
                                // is it a streamed sound?
-                               if(!sound->isBuffered)
+                               if(!sound->m_isBuffered)
                                {
                                        // check for buffer refilling
-                                       alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+                                       alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
 
                                        if(info)
                                        {
-                                               specs.specs = sound->reader->getSpecs();
+                                               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->data_end)
+                                                       if(!sound->m_eos)
                                                        {
                                                                // read data
                                                                length = m_buffersize;
-                                                               sound->reader->read(length, buffer);
+                                                               sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
 
                                                                // looping necessary?
-                                                               if(length == 0 && sound->loopcount)
+                                                               if(length == 0 && sound->m_loopcount)
                                                                {
-                                                                       if(sound->loopcount > 0)
-                                                                               sound->loopcount--;
+                                                                       if(sound->m_loopcount > 0)
+                                                                               sound->m_loopcount--;
 
-                                                                       sound->reader->seek(0);
+                                                                       sound->m_reader->seek(0);
 
                                                                        length = m_buffersize;
-                                                                       sound->reader->read(length, buffer);
+                                                                       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)
                                                                {
-                                                                       sound->data_end = true;
                                                                        break;
                                                                }
 
                                                                // unqueue buffer
-                                                               alSourceUnqueueBuffers(sound->source, 1,
-                                                                                               &sound->buffers[sound->current]);
+                                                               alSourceUnqueueBuffers(sound->m_source, 1,
+                                                                                               &sound->m_buffers[sound->m_current]);
                                                                ALenum err;
                                                                if((err = alGetError()) != AL_NO_ERROR)
                                                                {
-                                                                       sound->data_end = true;
+                                                                       sound->m_eos = true;
                                                                        break;
                                                                }
 
                                                                // fill with new data
-                                                               alBufferData(sound->buffers[sound->current],
-                                                                                        sound->format,
-                                                                                        buffer, length *
+                                                               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->data_end = true;
+                                                                       sound->m_eos = true;
                                                                        break;
                                                                }
 
                                                                // and queue again
-                                                               alSourceQueueBuffers(sound->source, 1,
-                                                                                               &sound->buffers[sound->current]);
+                                                               alSourceQueueBuffers(sound->m_source, 1,
+                                                                                               &sound->m_buffers[sound->m_current]);
                                                                if(alGetError() != AL_NO_ERROR)
                                                                {
-                                                                       sound->data_end = true;
+                                                                       sound->m_eos = true;
                                                                        break;
                                                                }
 
-                                                               sound->current = (sound->current+1) %
-                                                                                                AUD_OPENAL_CYCLE_BUFFERS;
+                                                               sound->m_current = (sound->m_current+1) %
+                                                                                                AUD_OpenALHandle::CYCLE_BUFFERS;
                                                        }
                                                        else
                                                                break;
@@ -236,18 +909,18 @@ void AUD_OpenALDevice::updateStreams()
                                }
 
                                // check if the sound has been stopped
-                               alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+                               alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
 
                                if(info != AL_PLAYING)
                                {
                                        // if it really stopped
-                                       if(sound->data_end)
+                                       if(sound->m_eos)
                                        {
-                                               if(sound->stop)
-                                                       sound->stop(sound->stop_data);
+                                               if(sound->m_stop)
+                                                       sound->m_stop(sound->m_stop_data);
 
                                                // pause or
-                                               if(sound->keep)
+                                               if(sound->m_keep)
                                                        pauseSounds.push_back(sound);
                                                // stop
                                                else
@@ -255,15 +928,15 @@ void AUD_OpenALDevice::updateStreams()
                                        }
                                        // continue playing
                                        else
-                                               alSourcePlay(sound->source);
+                                               alSourcePlay(sound->m_source);
                                }
                        }
 
                        for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
-                               pause(*it);
+                               (*it)->pause();
 
                        for(it = stopSounds.begin(); it != stopSounds.end(); it++)
-                               stop(*it);
+                               (*it)->stop();
 
                        pauseSounds.clear();
                        stopSounds.clear();
@@ -272,7 +945,7 @@ void AUD_OpenALDevice::updateStreams()
                }
 
                // stop thread
-               if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR))
+               if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
                {
                        m_playing = false;
                        unlock();
@@ -293,19 +966,6 @@ void AUD_OpenALDevice::updateStreams()
 /**************************** IDevice Code ************************************/
 /******************************************************************************/
 
-bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
-{
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
-               if(*i == handle)
-                       return true;
-       for(AUD_HandleIterator i = m_pausedSounds->begin();
-               i != m_pausedSounds->end(); i++)
-               if(*i == handle)
-                       return true;
-       return false;
-}
-
 static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
 
 AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
@@ -358,9 +1018,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
        m_buffersize = buffersize;
        m_playing = false;
 
-       m_playingSounds = new std::list<AUD_OpenALHandle*>();
-       m_pausedSounds = new std::list<AUD_OpenALHandle*>();
-       m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
+//     m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
 
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
@@ -375,46 +1033,23 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
 
 AUD_OpenALDevice::~AUD_OpenALDevice()
 {
-       AUD_OpenALHandle* sound;
-
        lock();
        alcSuspendContext(m_context);
 
-       // delete all playing sounds
-       while(!m_playingSounds->empty())
-       {
-               sound = *(m_playingSounds->begin());
-               alDeleteSources(1, &sound->source);
-               if(!sound->isBuffered)
-               {
-                       delete sound->reader;
-                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-               }
-               delete sound;
-               m_playingSounds->erase(m_playingSounds->begin());
-       }
+       while(!m_playingSounds.empty())
+               m_playingSounds.front()->stop();
+
+       while(!m_pausedSounds.empty())
+               m_pausedSounds.front()->stop();
 
-       // delete all paused sounds
-       while(!m_pausedSounds->empty())
-       {
-               sound = *(m_pausedSounds->begin());
-               alDeleteSources(1, &sound->source);
-               if(!sound->isBuffered)
-               {
-                       delete sound->reader;
-                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-               }
-               delete sound;
-               m_pausedSounds->erase(m_pausedSounds->begin());
-       }
 
        // delete all buffered factories
-       while(!m_bufferedFactories->empty())
+       /*while(!m_bufferedFactories->empty())
        {
                alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
                delete *m_bufferedFactories->begin();
                m_bufferedFactories->erase(m_bufferedFactories->begin());
-       }
+       }*/
 
        alcProcessContext(m_context);
 
@@ -422,9 +1057,7 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
        unlock();
        pthread_join(m_thread, NULL);
 
-       delete m_playingSounds;
-       delete m_pausedSounds;
-       delete m_bufferedFactories;
+       //delete m_bufferedFactories;
 
        // quit OpenAL
        alcMakeContextCurrent(NULL);
@@ -530,120 +1163,54 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
        return valid;
 }
 
-static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
-                                                                        "generated.";
-static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
-                                                                        "generated.";
-static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
-                                                                "queued to the source.";
-static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
-                                                                         "filled with data.";
-
-AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
 {
-       AUD_OpenALHandle* sound = NULL;
-
-       AUD_DeviceSpecs specs = m_specs;
-       specs.specs = reader->getSpecs();
+       AUD_Specs specs = reader->getSpecs();
 
        // check format
-       bool valid = specs.channels != AUD_CHANNELS_INVALID;
+       if(specs.channels == AUD_CHANNELS_INVALID)
+               return AUD_Reference<AUD_IHandle>();
 
        if(m_specs.format != AUD_FORMAT_FLOAT32)
                reader = new AUD_ConverterReader(reader, m_specs);
 
-       // create the handle
-       sound = new AUD_OpenALHandle;
-       sound->keep = keep;
-       sound->reader = reader;
-       sound->current = 0;
-       sound->isBuffered = false;
-       sound->data_end = false;
-       sound->loopcount = 0;
-       sound->stop = NULL;
-       sound->stop_data = NULL;
-
-       valid &= getFormat(sound->format, specs.specs);
+       ALenum format;
 
-       if(!valid)
-       {
-               delete sound;
-               delete reader;
-               return NULL;
-       }
+       if(!getFormat(format, specs))
+               return AUD_Reference<AUD_IHandle>();
 
        lock();
        alcSuspendContext(m_context);
 
-       // OpenAL playback code
+       AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound;
+
        try
        {
-               alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-               if(alGetError() != AL_NO_ERROR)
-                       AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
-               try
-               {
-                       sample_t* buf;
-                       int length;
-
-                       for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
-                       {
-                               length = m_buffersize;
-                               reader->read(length, buf);
-                               alBufferData(sound->buffers[i], sound->format, buf,
-                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
-                                                        specs.rate);
-                               if(alGetError() != AL_NO_ERROR)
-                                       AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
-                       }
-
-                       alGenSources(1, &sound->source);
-                       if(alGetError() != AL_NO_ERROR)
-                               AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
-                       try
-                       {
-                               alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
-                                                                        sound->buffers);
-                               if(alGetError() != AL_NO_ERROR)
-                                       AUD_THROW(AUD_ERROR_OPENAL, queue_error);
-                       }
-                       catch(AUD_Exception&)
-                       {
-                               alDeleteSources(1, &sound->source);
-                               throw;
-                       }
-               }
-               catch(AUD_Exception&)
-               {
-                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-                       throw;
-               }
+               // create the handle
+               sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep);
        }
        catch(AUD_Exception&)
        {
-               delete sound;
-               delete reader;
                alcProcessContext(m_context);
                unlock();
                throw;
        }
 
+       alcProcessContext(m_context);
+
        // play sound
-       m_playingSounds->push_back(sound);
-       alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+       m_playingSounds.push_back(sound);
 
        start();
 
-       alcProcessContext(m_context);
        unlock();
 
-       return sound;
+       return AUD_Reference<AUD_IHandle>(sound);
 }
 
-AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
 {
+       /* AUD_XXX disabled
        AUD_OpenALHandle* sound = NULL;
 
        lock();
@@ -661,7 +1228,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                                sound->keep = keep;
                                sound->current = -1;
                                sound->isBuffered = true;
-                               sound->data_end = true;
+                               sound->eos = true;
                                sound->loopcount = 0;
                                sound->stop = NULL;
                                sound->stop_data = NULL;
@@ -713,264 +1280,24 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        unlock();
 
        if(sound)
-               return sound;
+               return sound;*/
 
        return play(factory->createReader(), keep);
 }
 
-bool AUD_OpenALDevice::pause(AUD_Handle* handle)
-{
-       bool result = false;
-
-       lock();
-
-       // only songs that are played can be paused
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
-       {
-               if(*i == handle)
-               {
-                       m_pausedSounds->push_back(*i);
-                       alSourcePause((*i)->source);
-                       m_playingSounds->erase(i);
-                       result = true;
-                       break;
-               }
-       }
-
-       unlock();
-
-       return result;
-}
-
-bool AUD_OpenALDevice::resume(AUD_Handle* handle)
-{
-       bool result = false;
-
-       lock();
-
-       // only songs that are paused can be resumed
-       for(AUD_HandleIterator i = m_pausedSounds->begin();
-               i != m_pausedSounds->end(); i++)
-       {
-               if(*i == handle)
-               {
-                       m_playingSounds->push_back(*i);
-                       start();
-                       m_pausedSounds->erase(i);
-                       result = true;
-                       break;
-               }
-       }
-
-       unlock();
-
-       return result;
-}
-
-bool AUD_OpenALDevice::stop(AUD_Handle* handle)
-{
-       AUD_OpenALHandle* sound;
-
-       bool result = false;
-
-       lock();
-
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
-       {
-               if(*i == handle)
-               {
-                       sound = *i;
-                       alDeleteSources(1, &sound->source);
-                       if(!sound->isBuffered)
-                       {
-                               delete sound->reader;
-                               alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-                       }
-                       delete *i;
-                       m_playingSounds->erase(i);
-                       result = true;
-                       break;
-               }
-       }
-       if(!result)
-       {
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
-               {
-                       if(*i == handle)
-                       {
-                               sound = *i;
-                               alDeleteSources(1, &sound->source);
-                               if(!sound->isBuffered)
-                               {
-                                       delete sound->reader;
-                                       alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
-                               }
-                               delete *i;
-                               m_pausedSounds->erase(i);
-                               result = true;
-                               break;
-                       }
-               }
-       }
-
-       unlock();
-
-       return result;
-}
-
-bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
-{
-       bool result = false;
-
-       lock();
-
-       if(isValid(handle))
-               result = ((AUD_OpenALHandle*)handle)->keep;
-
-       unlock();
-
-       return result;
-}
-
-bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
-{
-       bool result = false;
-
-       lock();
-
-       if(isValid(handle))
-       {
-               ((AUD_OpenALHandle*)handle)->keep = keep;
-               result = true;
-       }
-
-       unlock();
-
-       return result;
-}
-
-bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
-{
-       bool result = false;
-
-       lock();
-
-       if(isValid(handle))
-       {
-               AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
-               if(alhandle->isBuffered)
-                       alSourcef(alhandle->source, AL_SEC_OFFSET, position);
-               else
-               {
-                       alhandle->reader->seek((int)(position *
-                                                                                alhandle->reader->getSpecs().rate));
-                       alhandle->data_end = false;
-
-                       ALint info;
-
-                       alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
-
-                       if(info != AL_PLAYING)
-                       {
-                               if(info == AL_PAUSED)
-                                       alSourceStop(alhandle->source);
-
-                               alSourcei(alhandle->source, AL_BUFFER, 0);
-                               alhandle->current = 0;
-
-                               ALenum err;
-                               if((err = alGetError()) == AL_NO_ERROR)
-                               {
-                                       sample_t* buf;
-                                       int length;
-                                       AUD_DeviceSpecs specs = m_specs;
-                                       specs.specs = alhandle->reader->getSpecs();
-
-                                       for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
-                                       {
-                                               length = m_buffersize;
-                                               alhandle->reader->read(length, buf);
-                                               alBufferData(alhandle->buffers[i], alhandle->format,
-                                                                        buf,
-                                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
-                                                                        specs.rate);
-
-                                               if(alGetError() != AL_NO_ERROR)
-                                                       break;
-                                       }
-
-                                       alSourceQueueBuffers(alhandle->source,
-                                                                                AUD_OPENAL_CYCLE_BUFFERS,
-                                                                                alhandle->buffers);
-                               }
-
-                               alSourceRewind(alhandle->source);
-                       }
-               }
-               result = true;
-       }
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
-{
-       float position = 0.0f;
-
-       lock();
-
-       if(isValid(handle))
-       {
-               AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
-               alGetSourcef(h->source, AL_SEC_OFFSET, &position);
-               if(!h->isBuffered)
-               {
-                       AUD_Specs specs = h->reader->getSpecs();
-                       position += (h->reader->getPosition() - m_buffersize *
-                                                                       AUD_OPENAL_CYCLE_BUFFERS) /
-                                          (float)specs.rate;
-               }
-       }
-
-       unlock();
-       return position;
-}
-
-AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
+void AUD_OpenALDevice::stopAll()
 {
-       AUD_Status status = AUD_STATUS_INVALID;
-
        lock();
+       alcSuspendContext(m_context);
 
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
-       {
-               if(*i == handle)
-               {
-                       status = AUD_STATUS_PLAYING;
-                       break;
-               }
-       }
-       if(status == AUD_STATUS_INVALID)
-       {
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
-               {
-                       if(*i == handle)
-                       {
-                               status = AUD_STATUS_PAUSED;
-                               break;
-                       }
-               }
-       }
+       while(!m_playingSounds.empty())
+               m_playingSounds.front()->stop();
 
-       unlock();
+       while(!m_pausedSounds.empty())
+               m_pausedSounds.front()->stop();
 
-       return status;
+       alcProcessContext(m_context);
+       unlock();
 }
 
 void AUD_OpenALDevice::lock()
@@ -995,80 +1322,6 @@ void AUD_OpenALDevice::setVolume(float volume)
        alListenerf(AL_GAIN, volume);
 }
 
-float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
-{
-       lock();
-       float result = std::numeric_limits<float>::quiet_NaN();
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
-{
-       lock();
-       bool result = isValid(handle);
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
-{
-       lock();
-       float result = std::numeric_limits<float>::quiet_NaN();
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
-{
-       lock();
-       bool result = isValid(handle);
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
-       unlock();
-       return result;
-}
-
-int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
-{
-       lock();
-       int result = 0;
-       if(isValid(handle))
-               result = ((AUD_OpenALHandle*)handle)->loopcount;
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
-{
-       lock();
-       bool result = isValid(handle);
-       if(result)
-               ((AUD_OpenALHandle*)handle)->loopcount = count;
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
-       lock();
-       bool result = isValid(handle);
-       if(result)
-       {
-               AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
-               h->stop = callback;
-               h->stop_data = data;
-       }
-       unlock();
-       return result;
-}
-
 /* AUD_XXX Temorary disabled
 
 bool AUD_OpenALDevice::bufferFactory(void *value)
@@ -1109,7 +1362,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
 
                if(!getFormat(format, specs.specs))
                {
-                       delete reader;
                        return false;
                }
 
@@ -1147,7 +1399,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
                catch(AUD_Exception&)
                {
                        delete bf;
-                       delete reader;
                        alcProcessContext(m_context);
                        unlock();
                        return false;
@@ -1219,8 +1470,7 @@ void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
 
 AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
 {
-       // AUD_XXX not implemented yet
-       return AUD_Quaternion(0, 0, 0, 0);
+       return m_orientation;
 }
 
 void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
@@ -1239,6 +1489,7 @@ void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
        direction[5] = 2 * (orientation.w() * orientation.x() +
                                                orientation.y() * orientation.z());
        alListenerfv(AL_ORIENTATION, direction);
+       m_orientation = orientation;
 }
 
 float AUD_OpenALDevice::getSpeedOfSound() const
@@ -1308,333 +1559,3 @@ void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
                alDistanceModel(AL_NONE);
        }
 }
-
-AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
-{
-       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-       ALfloat p[3];
-       lock();
-
-       if(isValid(handle))
-       {
-               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
-               result = AUD_Vector3(p[0], p[1], p[2]);
-       }
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
-                                  (ALfloat*)location.get());
-
-       unlock();
-       return result;
-}
-
-AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
-{
-       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-       ALfloat v[3];
-       lock();
-
-       if(isValid(handle))
-       {
-               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
-               result = AUD_Vector3(v[0], v[1], v[2]);
-       }
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
-                                  (ALfloat*)velocity.get());
-
-       unlock();
-       return result;
-}
-
-AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
-{
-       // AUD_XXX not implemented yet
-       return AUD_Quaternion(0, 0, 0, 0);
-}
-
-bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-       {
-               ALfloat direction[3];
-               direction[0] = -2 * (orientation.w() * orientation.y() +
-                                                        orientation.x() * orientation.z());
-               direction[1] = 2 * (orientation.x() * orientation.w() -
-                                                       orientation.z() * orientation.y());
-               direction[2] = 2 * (orientation.x() * orientation.x() +
-                                                       orientation.y() * orientation.y()) - 1;
-               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
-                                  direction);
-       }
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
-{
-       int result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
-                                 relative);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
-                                 volume);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
-                                 volume);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
-                                 distance);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
-                                 distance);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
-                                 factor);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
-                             &nbs