Merging trunk up to r38932.
authorJoerg Mueller <nexyon@gmail.com>
Tue, 2 Aug 2011 12:16:06 +0000 (12:16 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Tue, 2 Aug 2011 12:16:06 +0000 (12:16 +0000)
390 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/fftw/AUD_BandPassReader.cpp
intern/audaspace/intern/AUD_3DMath.h
intern/audaspace/intern/AUD_AnimateableProperty.cpp [new file with mode: 0644]
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_DefaultMixer.cpp [deleted file]
intern/audaspace/intern/AUD_FileFactory.cpp
intern/audaspace/intern/AUD_FileFactory.h
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_IHandle.h [new file with mode: 0644]
intern/audaspace/intern/AUD_IReader.h
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 [moved from intern/audaspace/intern/AUD_ResampleFactory.h with 81% similarity]
intern/audaspace/intern/AUD_ResampleReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_ResampleReader.h [moved from intern/audaspace/intern/AUD_DefaultMixer.h with 57% similarity]
intern/audaspace/intern/AUD_SequencerEntry.cpp [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.cpp [new file with mode: 0644]
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/sndfile/AUD_SndFileFactory.cpp
intern/audaspace/sndfile/AUD_SndFileFactory.h
intern/audaspace/sndfile/AUD_SndFileReader.cpp
intern/audaspace/sndfile/AUD_SndFileReader.h
release/datafiles/blenderbuttons
release/scripts/modules/bpy_types.py
release/scripts/modules/mocap_constraints.py [new file with mode: 0644]
release/scripts/modules/mocap_tools.py [new file with mode: 0644]
release/scripts/modules/retarget.py [new file with mode: 0644]
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_userpref.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/ui_mocap.py [new file with mode: 0644]
source/blender/CMakeLists.txt
source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.c
source/blender/blenkernel/BKE_animsys.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_object.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/fmodifier.c
source/blender/blenkernel/intern/idcode.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/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/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_ipo_utils.c
source/blender/editors/animation/anim_markers.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/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/editaction_gpencil.c
source/blender/editors/include/ED_anim_api.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_style.c
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/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_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_outliner/CMakeLists.txt
source/blender/editors/space_outliner/outliner.c [deleted file]
source/blender/editors/space_outliner/outliner_draw.c [new file with mode: 0644]
source/blender/editors/space_outliner/outliner_edit.c [new file with mode: 0644]
source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_ops.c
source/blender/editors/space_outliner/outliner_select.c [new file with mode: 0644]
source/blender/editors/space_outliner/outliner_tools.c [new file with mode: 0644]
source/blender/editors/space_outliner/outliner_tree.c [new file with mode: 0644]
source/blender/editors/space_outliner/space_outliner.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_text/text_draw.c
source/blender/editors/space_time/space_time.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_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_sequence_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_armature.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_fcurve.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/blender/windowmanager/intern/wm_files.c
source/blenderplayer/bad_level_call_stubs/stubs.c
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_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/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 36ef915..d1fc859 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 7eef13b..6f3d184 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,13 +86,13 @@ 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_I3DDevice.h
+       intern/AUD_I3DHandle.h
        intern/AUD_IDevice.h
        intern/AUD_IFactory.h
+       intern/AUD_IHandle.h
        intern/AUD_IReader.h
        intern/AUD_LinearResampleFactory.cpp
        intern/AUD_LinearResampleFactory.h
@@ -104,9 +108,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 +141,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
index d609249..0dffa7f 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 3c3b32c..5838cce 100644 (file)
@@ -33,6 +33,7 @@
 #define AUD_ACCUMULATORFACTORY
 
 #include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
 
 /**
  * This factory creates an accumulator reader.
@@ -55,9 +56,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_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       static sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless);
+       static sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
 };
 
 #endif //AUD_ACCUMULATORFACTORY
index 563722d..29ff6d9 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 436e646..644bcff 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,27 @@ 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:
        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];
        }
 
        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);
 
        virtual sample_t filter()=0;
+       virtual void sampleRateChanged(AUD_SampleRate rate);
 };
 
 #endif //AUD_BASEIIRFILTERREADER
index ea957c8..4b45512 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 c8b7314..16d0b3d 100644 (file)
 #ifndef AUD_BUTTERWORTHFACTORY
 #define AUD_BUTTERWORTHFACTORY
 
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
 
 /**
  * This factory creates a butterworth 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 2f9bb77..e6c8332 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 a969db7..6d53ede 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 1d2d99a..e452870 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 1e67cd6..5ab7f85 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 374b876..7d58b3d 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 5f0af66..a89afe7 100644 (file)
 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 7a40f1f..e1e6ba5 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 52a299c..f2be713 100644 (file)
@@ -44,12 +44,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 +61,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 113bed1..e988274 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(memcmp(&specs1, &specs2, sizeof(AUD_Specs)))
+                               length = len;
+                       else
+                       {
+                               int len2 = length - len;
+                               m_reader2->read(len2, eos, buffer + specs1.channels * len);
+                               length = len + len2;
+                       }
                }
        }
        else
        {
-               m_reader2->read(length, buffer);
+               m_reader2->read(length, eos, buffer);
        }
 }
index 7b3b812..86f636e 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "AUD_IReader.h"
 #include "AUD_Buffer.h"
+#include "AUD_Reference.h"
 
 /**
  * This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ 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.
@@ -72,7 +73,7 @@ public:
         * \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 +85,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..19c1a0f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $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>
+
+class AUD_DynamicIIRFilterFactory : public AUD_EffectFactory
+{
+public:
+       AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory);
+
+       virtual AUD_Reference<AUD_IReader> createReader();
+
+       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..92f491f
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * $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"
+
+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 a0d9256..6173ffb 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 a6a28ee..72fdb3f 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 3ad9f67..4d14af7 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 fb8066f..c03abd1 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 069317d..80df7e9 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 45ee811..a480a05 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 d887e9e..635873e 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 b85475b..d8314c7 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 6114bb4..4a6050c 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 fb92719..e702ac0 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 61008ee..399ec5c 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 48f4c1b..51d5f55 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:
        /**
@@ -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 ff90ce6..f6ccda6 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 d48ad45..0e92ab1 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 0d55421..1bfb9b9 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 af50b6f..41de67d 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 62ea01b..8d1dd14 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 f93f4b3..c04bfe8 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 d67fbb4..dc31477 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 4375ed9..d9bee6f 100644 (file)
@@ -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&);
@@ -62,12 +62,12 @@ public:
         * \param end The desired end sample (exklusive), a negative value signals
         *            that it should play to the end.
         */
-       AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
+       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 49d3481..fd39ac9 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 dfbbbe4..03c00dc 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 b2e8e97..de67a44 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 4501790..5ccf7e5 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 d24a04b..3ef25c3 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 d60c0bd..6558663 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:
        /**
@@ -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 fa14055..e5f2193 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 4ae0c49..908591a 100644 (file)
@@ -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 b4ae858..e520287 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 8fa5be9..2642d41 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 e2e89e2..81dd6e4 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 120cebc..7418531 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&);
@@ -55,9 +55,12 @@ public:
         * \param reader The reader to read from.
         * \param pitch The size of the buffer.
         */
-       AUD_PitchReader(AUD_IReader* reader, float pitch);
+       AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch);
 
        virtual AUD_Specs getSpecs() const;
+
+       float getPitch() const;
+       void setPitch(float pitch);
 };
 
 #endif //AUD_PITCHREADER
index 609d827..cbb676a 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 c3529c7..16b4446 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 22b12e3..060a618 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 7b20546..b501b4e 100644 (file)
@@ -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 a4a0393..73f6830 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 e12f2b2..da0add9 100644 (file)
@@ -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 a075773..226085a 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 8060e98..2128436 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 6d8368d..befcc30 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 ed19a0f..cdb4caf 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 c13a0d0..d514bfd 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 3223201..ac7ec08 100644 (file)
@@ -44,12 +44,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 +61,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 e64cf79..a0dc12f 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(memcmp(&specs, &s2, sizeof(AUD_Specs)))
+               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 b256aad..a87f1fd 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "AUD_IReader.h"
 #include "AUD_Buffer.h"
+#include "AUD_Reference.h"
 
 /**
  * This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ 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.
@@ -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 166fbf6..17cefd4 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 fa40ca1..bcc08e7 100644 (file)
@@ -57,14 +57,14 @@ 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.
         */
        float getVolume() const;
 
-       virtual AUD_IReader* createReader() const;
+       virtual AUD_Reference<AUD_IReader> createReader();
 };
 
 #endif //AUD_VOLUMEFACTORY
index 71e7b76..40fc8a5 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()
+{
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
+}
+
+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();
+
+       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);
+
+       m_device->unlock();
+
+       return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
+
+       if(!m_status)
+               return result;
 
-/// Saves the data for playback.
-struct AUD_OpenALHandle : AUD_Handle
+       m_device->lock();
+
+       alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+       m_device->unlock();
+
+       return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
 {
-       /// Whether it's a buffered or a streamed source.
-       bool isBuffered;
+       if(!m_status)
+               return false;
 
-       /// The reader source.
-       AUD_IReader* reader;
+       m_device->lock();
 
-       /// Whether to keep the source if end of it is reached.
-       bool keep;
+       alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
 
-       /// OpenAL sample format.
-       ALenum format;
+       m_device->unlock();
 
-       /// OpenAL source.
-       ALuint source;
+       return true;
+}
 
-       /// OpenAL buffers.
-       ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
+{
+       float result = std::numeric_limits<float>::quiet_NaN();
 
-       /// The first buffer to be read next.
-       int current;
+       if(!m_status)
+               return result;
 
-       /// Whether the stream doesn't return any more data.
-       bool data_end;
+       m_device->lock();
 
-       /// The loop count of the source.
-       int loopcount;
+       alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
 
-       /// The stop callback.
-       stopCallback stop;
+       m_device->unlock();
 
-       /// Stop callback data.
-       void* stop_data;
-};
+       return result;
+}
 
-struct AUD_OpenALBufferedFactory
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
 {
-       /// The factory.
-       AUD_IFactory* factory;
+       if(!m_status)
+               return false;
 
-       /// The OpenAL buffer.
-       ALuint buffer;
-};
+       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 +800,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 +820,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 +908,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 +927,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 +944,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 +965,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 +1017,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 +1032,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 +1056,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 +1162,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 +1227,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 +1279,9 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        unlock();
 
        if(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)
-{
-       AUD_Status status = AUD_STATUS_INVALID;
-
-       lock();
-
-       for(AUD_HandleIterator i = m_playingSounds->begin();
-               i != m_playingSounds->end(); i++)
-       {
-               if(*i == handle)
-               {
-                       status = AUD_STATUS_PLAYING;
-                       break;
-               }
-       }
-       if(status == AUD_STATUS_INVALID)
-       {
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
-               {
-                       if(*i == handle)
-                       {
-                               status = AUD_STATUS_PAUSED;
-                               break;
-                       }
-               }
-       }
-
-       unlock();
+               return sound;*/
 
-       return status;
+       return play(factory->createReader(), keep);
 }
 
 void AUD_OpenALDevice::lock()
@@ -995,80 +1306,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 +1346,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
 
                if(!getFormat(format, specs.specs))
                {
-                       delete reader;
                        return false;
                }
 
@@ -1147,7 +1383,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
                catch(AUD_Exception&)
                {
                        delete bf;
-                       delete reader;
                        alcProcessContext(m_context);
                        unlock();
                        return false;
@@ -1308,333 +1543,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,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
-                                 angle);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
-                                 angle);
-
-       unlock();
-       return result;
-}
-
-float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
-{
-       float result = std::numeric_limits<float>::quiet_NaN();;
-
-       lock();
-
-       if(isValid(handle))
-               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
-                                        &result);
-
-       unlock();
-       return result;
-}
-
-bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
-{
-       lock();
-       bool result = isValid(handle);
-
-       if(result)
-               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
-                                 volume);
-
-       unlock();
-       return result;
-}
index 127f69b..3ba761b 100644 (file)
 #define AUD_OPENALDEVICE
 
 #include "AUD_IDevice.h"
+#include "AUD_IHandle.h"
 #include "AUD_I3DDevice.h"
-struct AUD_OpenALHandle;
-struct AUD_OpenALBufferedFactory;
+#include "AUD_I3DHandle.h"
+#include "AUD_Buffer.h"
+//struct AUD_OpenALBufferedFactory;
 
 #include <AL/al.h>
 #include <AL/alc.h>
@@ -48,6 +50,100 @@ struct AUD_OpenALBufferedFactory;
 class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
 {
 private:
+       /// Saves the data for playback.
+       class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
+       {
+       public:
+               static const int CYCLE_BUFFERS = 3;
+
+               /// Whether it's a buffered or a streamed source.
+               bool m_isBuffered;
+
+               /// The reader source.
+               AUD_Reference<AUD_IReader> m_reader;
+
+               /// Whether to keep the source if end of it is reached.
+               bool m_keep;
+
+               /// OpenAL sample format.
+               ALenum m_format;
+
+               /// OpenAL source.
+               ALuint m_source;
+
+               /// OpenAL buffers.
+               ALuint m_buffers[CYCLE_BUFFERS];
+
+               /// The first buffer to be read next.
+               int m_current;
+
+               /// Whether the stream doesn't return any more data.
+               bool m_eos;
+
+               /// The loop count of the source.
+               int m_loopcount;
+
+               /// The stop callback.
+               stopCallback m_stop;
+
+               /// Stop callback data.
+               void* m_stop_data;
+
+               /// Current status of the handle
+               AUD_Status m_status;
+
+               /// Own device.
+               AUD_OpenALDevice* m_device;
+
+       public:
+
+               AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep);
+
+               virtual ~AUD_OpenALHandle() {}
+               virtual bool pause();
+               virtual bool resume();
+               virtual bool stop();
+               virtual bool getKeep();
+               virtual bool setKeep(bool keep);
+               virtual bool seek(float position);
+               virtual float getPosition();
+               virtual AUD_Status getStatus();
+               virtual float getVolume();
+               virtual bool setVolume(float volume);
+               virtual float getPitch();
+               virtual bool setPitch(float pitch);
+               virtual int getLoopCount();
+               virtual bool setLoopCount(int count);
+               virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+
+               virtual AUD_Vector3 getSourceLocation();
+               virtual bool setSourceLocation(const AUD_Vector3& location);
+               virtual AUD_Vector3 getSourceVelocity();
+               virtual bool setSourceVelocity(const AUD_Vector3& velocity);
+               virtual AUD_Quaternion getSourceOrientation();
+               virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+               virtual bool isRelative();
+               virtual bool setRelative(bool relative);
+               virtual float getVolumeMaximum();
+               virtual bool setVolumeMaximum(float volume);
+               virtual float getVolumeMinimum();
+               virtual bool setVolumeMinimum(float volume);
+               virtual float getDistanceMaximum();
+               virtual bool setDistanceMaximum(float distance);
+               virtual float getDistanceReference();
+               virtual bool setDistanceReference(float distance);
+               virtual float getAttenuation();
+               virtual bool setAttenuation(float factor);
+               virtual float getConeAngleOuter();
+               virtual bool setConeAngleOuter(float angle);
+               virtual float getConeAngleInner();
+               virtual bool setConeAngleInner(float angle);
+               virtual float getConeVolumeOuter();
+               virtual bool setConeVolumeOuter(float volume);
+       };
+
+       typedef std::list<AUD_Reference<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
+
        /**
         * The OpenAL device handle.
         */
@@ -71,17 +167,17 @@ private:
        /**
         * The list of sounds that are currently playing.
         */
-       std::list<AUD_OpenALHandle*>* m_playingSounds;
+       std::list<AUD_Reference<AUD_OpenALHandle> > m_playingSounds;
 
        /**
         * The list of sounds that are currently paused.
         */
-       std::list<AUD_OpenALHandle*>* m_pausedSounds;
+       std::list<AUD_Reference<AUD_OpenALHandle> > m_pausedSounds;
 
        /**
         * The list of buffered factories.
         */
-       std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+       //std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
 
        /**
         * The mutex for locking.
@@ -104,16 +200,14 @@ private:
        int m_buffersize;
 
        /**
-        * Starts the streaming thread.
+        * Device buffer.
         */
-       void start(bool join = true);
+       AUD_Buffer m_buffer;
 
        /**
-        * Checks if a handle is valid.
-        * \param handle The handle to check.
-        * \return Whether the handle is valid.
+        * Starts the streaming thread.
         */
-       bool isValid(AUD_Handle* handle);
+       void start(bool join = true);
 
        /**
         * Gets the format according to the specs.
@@ -147,27 +241,12 @@ public:
        virtual ~AUD_OpenALDevice();
 
        virtual AUD_DeviceSpecs getSpecs() const;
-       virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
-       virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
-       virtual bool pause(AUD_Handle* handle);
-       virtual bool resume(AUD_Handle* handle);
-       virtual bool stop(AUD_Handle* handle);
-       virtual bool getKeep(AUD_Handle* handle);
-       virtual bool setKeep(AUD_Handle* handle, bool keep);
-       virtual bool seek(AUD_Handle* handle, float position);
-       virtual float getPosition(AUD_Handle* handle);
-       virtual AUD_Status getStatus(AUD_Handle* handle);
+       virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+       virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
        virtual void lock();
        virtual void unlock();
        virtual float getVolume() const;
        virtual void setVolume(float volume);
-       virtual float getVolume(AUD_Handle* handle);
-       virtual bool setVolume(AUD_Handle* handle, float volume);
-       virtual float getPitch(AUD_Handle* handle);
-       virtual bool setPitch(AUD_Handle* handle, float pitch);
-       virtual int getLoopCount(AUD_Handle* handle);
-       virtual bool setLoopCount(AUD_Handle* handle, int count);
-       virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
 
        virtual AUD_Vector3 getListenerLocation() const;
        virtual void setListenerLocation(const AUD_Vector3& location);
@@ -181,30 +260,6 @@ public:
        virtual void setDopplerFactor(float factor);
        virtual AUD_DistanceModel getDistanceModel() const;
        virtual void setDistanceModel(AUD_DistanceModel model);
-       virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
-       virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
-       virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
-       virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
-       virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
-       virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
-       virtual bool isRelative(AUD_Handle* handle);
-       virtual bool setRelative(AUD_Handle* handle, bool relative);
-       virtual float getVolumeMaximum(AUD_Handle* handle);
-       virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
-       virtual float getVolumeMinimum(AUD_Handle* handle);
-       virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
-       virtual float getDistanceMaximum(AUD_Handle* handle);
-       virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
-       virtual float getDistanceReference(AUD_Handle* handle);
-       virtual bool setDistanceReference(AUD_Handle* handle, float distance);
-       virtual float getAttenuation(AUD_Handle* handle);
-       virtual bool setAttenuation(AUD_Handle* handle, float factor);
-       virtual float getConeAngleOuter(AUD_Handle* handle);
-       virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
-       virtual float getConeAngleInner(AUD_Handle* handle);
-       virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
-       virtual float getConeVolumeOuter(AUD_Handle* handle);
-       virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
 };
 
 #endif //AUD_OPENALDEVICE
index 22376a2..94e0257 100644 (file)
@@ -33,6 +33,7 @@
 #include "structmember.h"
 
 #include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
 #include "AUD_NULLDevice.h"
 #include "AUD_DelayFactory.h"
 #include "AUD_DoubleFactory.h"
@@ -91,7 +92,7 @@ static void
 Factory_dealloc(Factory* self)
 {
        if(self->factory)
-               delete self->factory;
+               delete reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory);
        Py_XDECREF(self->child_list);
        Py_TYPE(self)->tp_free((PyObject*)self);
 }
@@ -115,7 +116,7 @@ Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
                try
                {
-                       self->factory = new AUD_FileFactory(filename);
+                       self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
                }
                catch(AUD_Exception& e)
                {
@@ -143,9 +144,9 @@ static PyObject *
 Factory_sine(PyTypeObject* type, PyObject* args)
 {
        float frequency;
-       int rate = 44100;
+       double rate = 44100;
 
-       if(!PyArg_ParseTuple(args, "f|i:sine", &frequency, &rate))
+       if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate))
                return NULL;
 
        Factory *self;
@@ -155,7 +156,7 @@ Factory_sine(PyTypeObject* type, PyObject* args)
        {
                try
                {
-                       self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
+                       self->factory = new AUD_Reference<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
                }
                catch(AUD_Exception& e)
                {
@@ -194,7 +195,7 @@ Factory_file(PyTypeObject* type, PyObject* args)
        {
                try
                {
-                       self->factory = new AUD_FileFactory(filename);
+                       self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
                }
                catch(AUD_Exception& e)
                {
@@ -237,7 +238,7 @@ Factory_lowpass(Factory* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
                }
                catch(AUD_Exception& e)
                {
@@ -278,7 +279,7 @@ Factory_delay(Factory* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_DelayFactory(self->factory, delay);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), delay));
                }
                catch(AUD_Exception& e)
                {
@@ -322,7 +323,7 @@ Factory_join(Factory* self, PyObject* object)
 
                try
                {
-                       parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
                }
                catch(AUD_Exception& e)
                {
@@ -365,7 +366,7 @@ Factory_highpass(Factory* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
                }
                catch(AUD_Exception& e)
                {
@@ -406,7 +407,7 @@ Factory_limit(Factory* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_LimiterFactory(self->factory, start, end);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), start, end));
                }
                catch(AUD_Exception& e)
                {
@@ -450,7 +451,7 @@ Factory_pitch(Factory* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_PitchFactory(self->factory, factor);
+                       parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), factor));
                }