lib/fmod/system.rb in fmod-0.9.1 vs lib/fmod/system.rb in fmod-0.9.2
- old
+ new
@@ -1,22 +1,82 @@
module FMOD
+
+ ##
+ # The primary central class of FMOD. This class acts as a factory for creation
+ # of other core FMOD objects, and a centralized control interface. All core
+ # FMOD objects belong to a System object.
class System < Handle
+ ##
+ # Contains values for describing the current CPU time used by FMOD.
+ #
+ # @attr dsp [Float] The current DSP mixing engine CPU usage. Result will be
+ # from 0.0 to 100.0.
+ # @attr stream [Float] The current streaming engine CPU usage. Result will
+ # be from 0.0 to 100.0.
+ # @attr geometry [Float] The current geometry engine CPU usage. Result will
+ # be from 0.0 to 100.0.
+ # @attr update [Float] The current System::update CPU usage. Result will be
+ # from 0.0 to 100.0.
+ # @attr total [Float] The current total CPU usage. Result will be from 0 to
+ # 100.0.
CpuUsage = Struct.new(:dsp, :stream, :geometry, :update, :total)
+ ##
+ # Contains the amount of dedicated sound ram available if the platform
+ # supports it.
+ # @attr current [Integer] The currently allocated sound RAM memory at time
+ # of call.
+ # @attr max [Integer] The maximum allocated sound RAM memory since the
+ # System was created.
+ # @attr total [Integer] The total amount of sound RAM available on this
+ # device.
RamUsage = Struct.new(:current, :max, :total)
+ ##
+ # Contains information about file reads by FMOD.
+ # @attr sample [Integer] The total bytes read from file for loading
+ # sample data.
+ # @attr stream [Integer] The total bytes read from file for streaming
+ # sounds.
+ # @attr other [Integer] The total bytes read for non-audio data such
+ # as FMOD Studio banks.
FileUsage = Struct.new(:sample, :stream, :other)
+ # Represents a logical position of a speaker.
+ # @attr index [Integer] The index of the speaker.
+ # @attr x [Float] The x-coordinate of the speaker.
+ # @attr y [Float] The y-coordinate of the speaker.
+ # @attr active [Boolean] +true+ if speaker will be enabled,
+ # otherwise +false+.
Speaker = Struct.new(:index, :x, :y, :active)
+ ##
+ # Defines the information to display for the selected plugin.
+ # @attr handle [Integer] The plugin handle.
+ # @attr type [Integer] The type of the plugin.
+ # @attr name [String] The name of the plugin.
+ # @attr version [Integer] The version number set by the plugin.
Plugin = Struct.new(:handle, :type, :name, :version)
+ # Describes the output format for the software mixer.
+ # @attr sample_rate [Integer] The rate in Hz, that the software mixer will
+ # run at. Specify values between 8000 and 192000.
+ # @attr speaker_mode [Integer] Speaker setup for the software mixer.
+ # @attr raw_channels [Integer] Number of output channels / speakers to
+ # initialize the sound card to in raw speaker mode.
SoftwareFormat = Struct.new(:sample_rate, :speaker_mode, :raw_channels)
+ ##
+ # The buffer size settings for the FMOD software mixing engine.
+ # @attr size [Integer] The mixer engine block size in samples. Default is
+ # 1024. (milliseconds = 1024 at 48khz = 1024 / 48000 * 1000 = 10.66ms).
+ # @attr count [Integer] The mixer engine number of buffers used. Default is
+ # 4. To get the total buffer size multiply the buffer length by the number
+ # of buffers. By default this would be 4*1024.
DspBuffer = Struct.new(:size, :count)
##
# The internal buffer size for streams opened after this call. Larger values
# will consume more memory, whereas smaller values may cause buffer
@@ -26,11 +86,14 @@
# @attr size [Integer] The size of stream file buffer. Default is 16384.
# @attr type [Integer] Type of unit for stream file buffer size.
# @see TimeUnit
StreamBuffer = Struct.new(:size, :type)
- def initialize(handle)
+ ##
+ # @param address [Pointer, Integer, String] The address of a native FMOD
+ # pointer.
+ def initialize(address)
super
@rolloff_callbacks = []
sig = [TYPE_VOIDP, TYPE_FLOAT]
abi = FMOD::ABI
cb = Closure::BlockCaller.new(TYPE_FLOAT, sig, abi) do |channel, distance|
@@ -41,10 +104,17 @@
distance
end
FMOD.invoke(:System_Set3DRolloffCallback, self, cb)
end
+ ##
+ # When FMOD wants to calculate 3D volume for a channel, this callback can be
+ # used to override the internal volume calculation based on distance.
+ #
+ # @param proc [Proc] Proc to call. Optional, must give block if nil.
+ # @yield [index] The block to call when rolloff is calculated.
+ # @return [void]
def on_rolloff(proc = nil, &block)
cb = proc || block
raise LocalJumpError, "No block given." if cb.nil?
@rolloff_callbacks << cb
end
@@ -875,46 +945,15 @@
self
end
# @!endgroup
+ # @!group Network
+ # @!attribute network_proxy
+ # @return [String] proxy server to use for internet connections.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
def network_proxy
buffer = "\0" * 512
FMOD.invoke(:System_GetNetworkProxy, self, buffer, 512)
# noinspection RubyResolve
buffer.delete("\0").force_encoding(Encoding::UTF_8)
@@ -923,134 +962,18 @@
def network_proxy=(url)
# noinspection RubyResolve
FMOD.invoke(:System_SetNetworkProxy, self, url.encode(Encoding::UTF_8))
end
+ # @!attribute network_timeout
+ # @return [Integer] the timeout, in milliseconds, for network streams.
integer_reader(:network_timeout, :System_GetNetworkTimeout)
integer_writer(:network_timeout=, :System_SetNetworkTimeout)
- integer_reader(:software_channels, :System_GetSoftwareChannels)
- integer_writer(:software_channels=, :System_SetSoftwareChannels, 0, 64)
+ # @!endgroup
-
-
- def master_channel_group
- FMOD.invoke(:System_GetMasterChannelGroup, self, group = int_ptr)
- ChannelGroup.new(group)
- end
-
- def master_sound_group
- FMOD.invoke(:System_GetMasterSoundGroup, self, group = int_ptr)
- SoundGroup.new(group)
- end
-
-
- def update
- FMOD.invoke(:System_Update, self)
- end
-
##
- # Closes the {System} object without freeing the object's memory, so the
- # system handle will still be valid.
- #
- # Closing the output renders objects created with this system object
- # invalid. Make sure any sounds, channel groups, geometry and DSP objects
- # are released before closing the system object.
- #
- # @return [void]
- def close
- FMOD.invoke(:System_Close, self)
- end
-
- ##
- # @!attribute [r] version
- # @return [String] the current version of FMOD being used.
- def version
- FMOD.invoke(:System_GetVersion, self, version = "\0" * SIZEOF_INT)
- FMOD.uint2version(version)
- end
-
- ##
- # Plays a sound object on a particular channel and {ChannelGroup}.
- #
- # When a sound is played, it will use the sound's default frequency and
- # priority.
- #
- # A sound defined as {Mode::THREE_D} will by default play at the position of
- # the listener.
- #
- # Channels are reference counted. If a channel is stolen by the FMOD
- # priority system, then the handle to the stolen voice becomes invalid, and
- # Channel based commands will not affect the new sound playing in its place.
- # If all channels are currently full playing a sound, FMOD will steal a
- # channel with the lowest priority sound. If more channels are playing than
- # are currently available on the sound-card/sound device or software mixer,
- # then FMOD will "virtualize" the channel. This type of channel is not
- # heard, but it is updated as if it was playing. When its priority becomes
- # high enough or another sound stops that was using a real hardware/software
- # channel, it will start playing from where it should be. This technique
- # saves CPU time (thousands of sounds can be played at once without actually
- # being mixed or taking up resources), and also removes the need for the
- # user to manage voices themselves. An example of virtual channel usage is a
- # dungeon with 100 torches burning, all with a looping crackling sound, but
- # with a sound-card that only supports 32 hardware voices. If the 3D
- # positions and priorities for each torch are set correctly, FMOD will play
- # all 100 sounds without any 'out of channels' errors, and swap the real
- # voices in and out according to which torches are closest in 3D space.
- # Priority for virtual channels can be changed in the sound's defaults, or
- # at runtime with {Channel.priority}.
- #
- # @param sound [Sound] The sound to play.
- # @param group [ChannelGroup] The {ChannelGroup} become a member of. This is
- # more efficient than using {Channel.group}, as it does it during the
- # channel setup, rather than connecting to the master channel group, then
- # later disconnecting and connecting to the new {ChannelGroup} when
- # specified. Specify +nil+ to ignore (use master {ChannelGroup}).
- # @param paused [Boolean] flag to specify whether to start the channel
- # paused or not. Starting a channel paused allows the user to alter its
- # attributes without it being audible, and un-pausing with
- # ChannelControl.resume actually starts the sound.
- #
- # @return [Channel] the newly playing channel.
- def play_sound(sound, group = nil, paused = false)
- FMOD.type?(sound, Sound)
- channel = int_ptr
- FMOD.invoke(:System_PlaySound, self, sound, group, paused.to_i, channel)
- Channel.new(channel)
- end
-
- def play_dsp(dsp, group = nil, paused = false)
- FMOD.type?(dsp, Dsp)
- channel = int_ptr
- FMOD.invoke(:System_PlayDSP, self, dsp, group, paused.to_i, channel)
- Channel.new(channel)
- end
-
- def [](index)
- reverb = Reverb.new
- FMOD.invoke(:System_GetReverbProperties, self, index, reverb)
- reverb
- end
-
- def []=(index, reverb)
- FMOD.type?(reverb, Reverb)
- FMOD.invoke(:System_SetReverbProperties, self, index, reverb)
- end
-
- def mixer_suspend
- FMOD.invoke(:System_MixerSuspend, self)
- if block_given?
- yield
- FMOD.invoke(:System_MixerResume, self)
- end
- end
-
- def mixer_resume
- FMOD.invoke(:System_MixerResume, self)
- end
-
- ##
# Route the signal from a channel group into a separate audio port on the
# output driver.
#
# Note that an FMOD port is a hardware specific reference, to hardware
# devices that exist on only certain platforms (like a console headset, or
@@ -1211,10 +1134,219 @@
def software_format=(format)
FMOD.type?(format, SoftwareFormat)
FMOD.invoke(:System_GetSoftwareFormat, self, *format.values)
end
+ ##
+ # Retrieves the internal master channel group. This is the default channel
+ # group that all channels play on.
+ #
+ # This channel group can be used to do things like set the master volume for
+ # all playing sounds. See the ChannelGroup API for more functionality.
+ # @return [ChannelGroup] the internal master channel group.
+ def master_channel_group
+ FMOD.invoke(:System_GetMasterChannelGroup, self, group = int_ptr)
+ ChannelGroup.new(group)
+ end
+
+ ##
+ # @@return [SoundGroup] the default sound group, where all sounds are placed
+ # when they are created.
+ def master_sound_group
+ FMOD.invoke(:System_GetMasterSoundGroup, self, group = int_ptr)
+ SoundGroup.new(group)
+ end
+
+ ##
+ # Closes the {System} object without freeing the object's memory, so the
+ # system handle will still be valid.
+ #
+ # Closing the output renders objects created with this system object
+ # invalid. Make sure any sounds, channel groups, geometry and DSP objects
+ # are released before closing the system object.
+ #
+ # @return [void]
+ def close
+ FMOD.invoke(:System_Close, self)
+ end
+
+ ##
+ # @!attribute [r] version
+ # @return [String] the current version of FMOD being used.
+ def version
+ FMOD.invoke(:System_GetVersion, self, version = "\0" * SIZEOF_INT)
+ FMOD.uint2version(version)
+ end
+
+ ##
+ # Plays a sound object on a particular channel and {ChannelGroup}.
+ #
+ # When a sound is played, it will use the sound's default frequency and
+ # priority.
+ #
+ # A sound defined as {Mode::THREE_D} will by default play at the position of
+ # the listener.
+ #
+ # Channels are reference counted. If a channel is stolen by the FMOD
+ # priority system, then the handle to the stolen voice becomes invalid, and
+ # Channel based commands will not affect the new sound playing in its place.
+ # If all channels are currently full playing a sound, FMOD will steal a
+ # channel with the lowest priority sound. If more channels are playing than
+ # are currently available on the sound-card/sound device or software mixer,
+ # then FMOD will "virtualize" the channel. This type of channel is not
+ # heard, but it is updated as if it was playing. When its priority becomes
+ # high enough or another sound stops that was using a real hardware/software
+ # channel, it will start playing from where it should be. This technique
+ # saves CPU time (thousands of sounds can be played at once without actually
+ # being mixed or taking up resources), and also removes the need for the
+ # user to manage voices themselves. An example of virtual channel usage is a
+ # dungeon with 100 torches burning, all with a looping crackling sound, but
+ # with a sound-card that only supports 32 hardware voices. If the 3D
+ # positions and priorities for each torch are set correctly, FMOD will play
+ # all 100 sounds without any 'out of channels' errors, and swap the real
+ # voices in and out according to which torches are closest in 3D space.
+ # Priority for virtual channels can be changed in the sound's defaults, or
+ # at runtime with {Channel.priority}.
+ #
+ # @param sound [Sound] The sound to play.
+ # @param group [ChannelGroup] The {ChannelGroup} become a member of. This is
+ # more efficient than using {Channel.group}, as it does it during the
+ # channel setup, rather than connecting to the master channel group, then
+ # later disconnecting and connecting to the new {ChannelGroup} when
+ # specified. Specify +nil+ to ignore (use master {ChannelGroup}).
+ # @param paused [Boolean] flag to specify whether to start the channel
+ # paused or not. Starting a channel paused allows the user to alter its
+ # attributes without it being audible, and un-pausing with
+ # ChannelControl.resume actually starts the sound.
+ #
+ # @return [Channel] the newly playing channel.
+ def play_sound(sound, group = nil, paused = false)
+ FMOD.type?(sound, Sound)
+ channel = int_ptr
+ FMOD.invoke(:System_PlaySound, self, sound, group, paused.to_i, channel)
+ Channel.new(channel)
+ end
+
+ ##
+ # Plays a sound object on a particular channel and {ChannelGroup}.
+ #
+ # When a sound is played, it will use the sound's default frequency and
+ # priority.
+ #
+ # A sound defined as {Mode::THREE_D} will by default play at the position of
+ # the listener.
+ #
+ # Channels are reference counted. If a channel is stolen by the FMOD
+ # priority system, then the handle to the stolen voice becomes invalid, and
+ # Channel based commands will not affect the new sound playing in its place.
+ # If all channels are currently full playing a sound, FMOD will steal a
+ # channel with the lowest priority sound. If more channels are playing than
+ # are currently available on the sound-card/sound device or software mixer,
+ # then FMOD will "virtualize" the channel. This type of channel is not
+ # heard, but it is updated as if it was playing. When its priority becomes
+ # high enough or another sound stops that was using a real hardware/software
+ # channel, it will start playing from where it should be. This technique
+ # saves CPU time (thousands of sounds can be played at once without actually
+ # being mixed or taking up resources), and also removes the need for the
+ # user to manage voices themselves. An example of virtual channel usage is a
+ # dungeon with 100 torches burning, all with a looping crackling sound, but
+ # with a sound-card that only supports 32 hardware voices. If the 3D
+ # positions and priorities for each torch are set correctly, FMOD will play
+ # all 100 sounds without any 'out of channels' errors, and swap the real
+ # voices in and out according to which torches are closest in 3D space.
+ # Priority for virtual channels can be changed in the sound's defaults, or
+ # at runtime with {Channel.priority}.
+ #
+ # @param dsp [Dsp] The DSP to play.
+ # @param group [ChannelGroup] The {ChannelGroup} become a member of. This is
+ # more efficient than using {Channel.group}, as it does it during the
+ # channel setup, rather than connecting to the master channel group, then
+ # later disconnecting and connecting to the new {ChannelGroup} when
+ # specified. Specify +nil+ to ignore (use master {ChannelGroup}).
+ # @param paused [Boolean] flag to specify whether to start the channel
+ # paused or not. Starting a channel paused allows the user to alter its
+ # attributes without it being audible, and un-pausing with
+ # ChannelControl.resume actually starts the sound.
+ #
+ # @return [Channel] the newly playing channel.
+ def play_dsp(dsp, group = nil, paused = false)
+ FMOD.type?(dsp, Dsp)
+ channel = int_ptr
+ FMOD.invoke(:System_PlayDSP, self, dsp, group, paused.to_i, channel)
+ Channel.new(channel)
+ end
+
+ ##
+ # Suspend mixer thread and relinquish usage of audio hardware while
+ # maintaining internal state.
+ #
+ # @overload mixer_suspend
+ # When called with a block, automatically resumes the mixer when the block
+ # exits.
+ # @yield Yields control back to receiver.
+ # @overload mixer_suspend
+ # When called without a block, user must call {#mixer_resume}.
+ #
+ # @return [void]
+ # @see mixer_resume
+ def mixer_suspend
+ FMOD.invoke(:System_MixerSuspend, self)
+ if block_given?
+ yield
+ FMOD.invoke(:System_MixerResume, self)
+ end
+ end
+
+ ##
+ # Resume mixer thread and reacquire access to audio hardware.
+ # @return [void]
+ # @see mixer_suspend
+ def mixer_resume
+ FMOD.invoke(:System_MixerResume, self)
+ end
+
+ ##
+ # Retrieves the current reverb environment for the specified reverb
+ # instance.
+ #
+ # @param index [Integer] Index of the particular reverb instance to target,
+ # from 0 to {FMOD::MAX_REVERB} inclusive.
+ #
+ # @return [Reverb] The specified Reverb instance.
+ def [](index)
+ reverb = Reverb.new
+ FMOD.invoke(:System_GetReverbProperties, self, index, reverb)
+ reverb
+ end
+
+ ##
+ # Sets parameters for the global reverb environment.
+ #
+ # @param index [Integer] Index of the particular reverb instance to target,
+ # from 0 to {FMOD::MAX_REVERB} inclusive.
+ # @param reverb [Reverb] A structure which defines the attributes for the
+ # reverb. Passing {FMOD::NULL} or +nil+ to this function will delete the
+ # physical reverb.
+ #
+ # @return [Reverb] the specified reverb.
+ def []=(index, reverb)
+ FMOD.type?(reverb, Reverb)
+ FMOD.invoke(:System_SetReverbProperties, self, index, reverb)
+ end
+
+ alias_method :get_reverb, :[]
+ alias_method :set_reverb, :[]=
+
+ ##
+ # @!attribute software_channels
+ # @return [Integer] the maximum number of software mixed channels possible.
+ integer_reader(:software_channels, :System_GetSoftwareChannels)
+ integer_writer(:software_channels=, :System_SetSoftwareChannels, 0, 64)
+
+ ##
+ # @!attribute stream_buffer
+ # @return [StreamBuffer] the internal buffer-size for streams.
def stream_buffer
size, type = "\0" * SIZEOF_INT, "\0" * SIZEOF_INT
FMOD.invoke(:System_GetStreamBufferSize, self, size, type)
StreamBuffer.new(size.unpack1('L'), type.unpack1('l'))
end
@@ -1223,19 +1355,34 @@
FMOD.type?(buffer, StreamBuffer)
raise RangeError, "size must be greater than 0" unless buffer.size > 0
FMOD.invoke(:System_SetStreamBufferSize, self, *buffer.values)
end
+ ##
+ # @!attribute stream_buffer
+ # @return [DspBuffer] the internal buffer-size for DSP units.
def dsp_buffer
size, count = "\0" * SIZEOF_INT, "\0" * SIZEOF_INT
FMOD.invoke(:System_GetDSPBufferSize, self, size, count)
DspBuffer.new(size.unpack1('L'), count.unpack1('l'))
end
def dsp_buffer=(buffer)
FMOD.type?(buffer, DspBuffer)
raise RangeError, "size must be greater than 0" unless buffer.size > 0
FMOD.invoke(:System_SetDSPBufferSize, self, *buffer.values)
+ end
+
+ ##
+ # Updates the FMOD system. This should be called once per "game tick", or
+ # once per frame in your application.
+ #
+ # @note Various callbacks are driven from this function, and it must be
+ # called for them to be invoked.
+ #
+ # @return [void]
+ def update
+ FMOD.invoke(:System_Update, self)
end
end
end