Class: SFML::Sound
- Inherits:
-
Object
- Object
- SFML::Sound
- Defined in:
- lib/sfml/audio/sound.rb
Overview
A short sound that plays from a SoundBuffer held entirely in memory. Cheap to create, suitable for game SFX (blips, hits, footsteps).
buffer = SFML::SoundBuffer.load("blip.wav")
sound = SFML::Sound.new(buffer, volume: 80, pitch: 1.2, looping: true)
sound.play
Instance Attribute Summary collapse
-
#buffer ⇒ Object
The buffer this Sound is currently bound to (the one passed to
.new, or whoever last calledbuffer=).
Instance Method Summary collapse
-
#attenuation ⇒ Object
Falloff sharpness with distance.
-
#attenuation=(value) ⇒ Object
Set the attenuation — see
#attenuation. -
#cone ⇒ Object
Directional-attenuation cone — see SFML::SoundCone.
-
#cone=(value) ⇒ Object
Set the cone.
-
#direction ⇒ Object
The direction the sound's cone points.
-
#direction=(value) ⇒ Object
Set the direction vector — accepts Vector3 or
[x, y, z]. -
#directional_attenuation_factor ⇒ Object
Multiplier on the Listener's directional attenuation cone.
-
#directional_attenuation_factor=(v) ⇒ Object
Set the directional-attenuation factor — see
#directional_attenuation_factor. -
#doppler_factor ⇒ Object
Per-source Doppler scale.
-
#doppler_factor=(v) ⇒ Object
Set the per-source Doppler scale.
-
#dup ⇒ Object
(also: #clone)
Independent copy — same buffer (buffers are shareable), independent transport state (volume/pan/spatialisation/etc).
-
#effect_processor=(callable) ⇒ Object
Install a real-time DSP filter.
-
#initialize(buffer, volume: 100.0, pitch: 1.0, looping: false) ⇒ Sound
constructor
A new instance of Sound.
-
#looping=(value) ⇒ Object
Toggle looping playback.
-
#looping? ⇒ Boolean
trueif the sound restarts after reaching the end. -
#max_distance ⇒ Object
The distance beyond which the source is fully attenuated.
-
#max_distance=(v) ⇒ Object
Set the max-distance — see
#max_distance. -
#max_gain ⇒ Object
The upper gain bound — see
#min_gain. -
#max_gain=(v) ⇒ Object
Set the max-gain cap — see
#max_gain. -
#min_distance ⇒ Object
Distance below which volume is not attenuated.
-
#min_distance=(value) ⇒ Object
Set the min-distance — see
#min_distance. -
#min_gain ⇒ Object
Output gain clamping.
-
#min_gain=(v) ⇒ Object
Set the min-gain floor — see
#min_gain. -
#pan ⇒ Object
Stereo pan in [-1.0, 1.0]: -1 = full left, 0 = centre, 1 = full right.
-
#pan=(v) ⇒ Object
Set the stereo pan — see
#pan. -
#pause ⇒ Object
Pause playback.
-
#paused? ⇒ Boolean
Convenience predicate for
status == :paused. -
#pitch ⇒ Object
Pitch multiplier.
-
#pitch=(value) ⇒ Object
Set the pitch multiplier — see
#pitch. -
#play ⇒ Object
Start playback.
-
#playing? ⇒ Boolean
Convenience predicate for
status == :playing. -
#playing_offset ⇒ Object
Current playback head as a SFML::Time.
-
#playing_offset=(value) ⇒ Object
Seek to
value(a SFML::Time, or seconds as a Numeric). -
#position ⇒ Object
---- 3D positional audio ----.
-
#position=(value) ⇒ Object
Set the 3D position — accepts Vector3 or
[x, y, z]. -
#relative_to_listener=(value) ⇒ Object
Toggle listener-relative positioning.
-
#relative_to_listener? ⇒ Boolean
If
true,#positionis interpreted relative to the listener (useful for HUD/UI sounds that should stay glued to the camera). -
#spatialization_enabled=(v) ⇒ Object
Toggle 3D spatialisation — see
#spatialization_enabled?. -
#spatialization_enabled? ⇒ Boolean
Whether 3D-positional / Doppler / cone math is applied at mix time.
-
#status ⇒ Object
Playback state — one of
:stopped,:paused,:playing. -
#stop ⇒ Object
Stop playback and rewind to the start.
-
#stopped? ⇒ Boolean
Convenience predicate for
status == :stopped. -
#velocity ⇒ Object
3D velocity in world units / second — used by the Doppler effect to shift pitch as the source approaches or recedes from the listener.
-
#velocity=(value) ⇒ Object
Set the 3D velocity — accepts a Vector3 or
[x, y, z]. -
#volume ⇒ Object
Playback volume in [0, 100] — 100 = unattenuated.
-
#volume=(value) ⇒ Object
Set the playback volume in [0, 100].
Constructor Details
#initialize(buffer, volume: 100.0, pitch: 1.0, looping: false) ⇒ Sound
Returns a new instance of Sound.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/sfml/audio/sound.rb', line 9 def initialize(buffer, volume: 100.0, pitch: 1.0, looping: false) raise ArgumentError, "Sound requires a SFML::SoundBuffer" unless buffer.is_a?(SoundBuffer) ptr = C::Audio.sfSound_create(buffer.handle) raise AudioError, "sfSound_create returned NULL" if ptr.null? @handle = FFI::AutoPointer.new(ptr, C::Audio.method(:sfSound_destroy)) @buffer = buffer # keep alive # @looping mirrors the loop flag because SFML 3's isLooping reads # through an OpenAL source that may be unallocated on systems # without an audio device (some CI runners). Caching on the Ruby # side keeps observable behaviour deterministic regardless. @looping = false self.volume = volume self.pitch = pitch self.looping = looping end |
Instance Attribute Details
#buffer ⇒ Object
The buffer this Sound is currently bound to (the one passed
to .new, or whoever last called buffer=). Returns nil
if the underlying source has none.
28 29 30 |
# File 'lib/sfml/audio/sound.rb', line 28 def buffer @buffer end |
Instance Method Details
#attenuation ⇒ Object
Falloff sharpness with distance. 0 = no falloff, 1 = realistic (1/distance), higher = steeper.
193 |
# File 'lib/sfml/audio/sound.rb', line 193 def attenuation = C::Audio.sfSound_getAttenuation(@handle) |
#attenuation=(value) ⇒ Object
Set the attenuation — see #attenuation.
196 197 198 |
# File 'lib/sfml/audio/sound.rb', line 196 def attenuation=(value) C::Audio.sfSound_setAttenuation(@handle, value.to_f) end |
#cone ⇒ Object
Directional-attenuation cone — see SFML::SoundCone.
108 109 110 |
# File 'lib/sfml/audio/sound.rb', line 108 def cone SoundCone.from_native(C::Audio.sfSound_getCone(@handle)) end |
#cone=(value) ⇒ Object
Set the cone. Accepts a SoundCone or a Hash with
inner_angle, outer_angle, outer_gain.
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/sfml/audio/sound.rb', line 114 def cone=(value) cone = case value when SoundCone then value when Hash then SoundCone.new(**value) else raise ArgumentError, "Sound#cone= expects SoundCone or Hash; got #{value.class}" end C::Audio.sfSound_setCone(@handle, cone.to_native) end |
#direction ⇒ Object
The direction the sound's cone points. Used together with #cone= for directional attenuation.
94 95 96 97 |
# File 'lib/sfml/audio/sound.rb', line 94 def direction v = C::Audio.sfSound_getDirection(@handle) Vector3.new(v[:x], v[:y], v[:z]) end |
#direction=(value) ⇒ Object
Set the direction vector — accepts Vector3 or [x, y, z].
100 101 102 103 104 105 |
# File 'lib/sfml/audio/sound.rb', line 100 def direction=(value) vec = value.is_a?(Vector3) ? value : Vector3.new(*value) packed = C::System::Vector3f.new packed[:x] = vec.x.to_f; packed[:y] = vec.y.to_f; packed[:z] = vec.z.to_f C::Audio.sfSound_setDirection(@handle, packed) end |
#directional_attenuation_factor ⇒ Object
Multiplier on the Listener's directional attenuation cone. 0 = source ignores the listener's facing direction (no cone falloff); 1 = full cone effect.
274 275 276 |
# File 'lib/sfml/audio/sound.rb', line 274 def directional_attenuation_factor C::Audio.sfSound_getDirectionalAttenuationFactor(@handle) end |
#directional_attenuation_factor=(v) ⇒ Object
Set the directional-attenuation factor — see
#directional_attenuation_factor.
280 281 282 |
# File 'lib/sfml/audio/sound.rb', line 280 def directional_attenuation_factor=(v) C::Audio.sfSound_setDirectionalAttenuationFactor(@handle, v.to_f) end |
#doppler_factor ⇒ Object
Per-source Doppler scale. 1.0 is realistic; bump it up for an exaggerated Doppler shift, drop to 0 to disable per-source.
88 89 |
# File 'lib/sfml/audio/sound.rb', line 88 def doppler_factor = C::Audio.sfSound_getDopplerFactor(@handle) # Set the per-source Doppler scale. See `#doppler_factor`. |
#doppler_factor=(v) ⇒ Object
Set the per-source Doppler scale. See #doppler_factor.
90 |
# File 'lib/sfml/audio/sound.rb', line 90 def doppler_factor=(v) C::Audio.sfSound_setDopplerFactor(@handle, v.to_f); end |
#dup ⇒ Object Also known as: clone
Independent copy — same buffer (buffers are shareable), independent transport state (volume/pan/spatialisation/etc).
286 287 288 289 290 291 292 293 294 295 |
# File 'lib/sfml/audio/sound.rb', line 286 def dup ptr = C::Audio.sfSound_copy(@handle) raise AudioError, "sfSound_copy returned NULL" if ptr.null? copy = self.class.allocate copy.instance_variable_set(:@handle, FFI::AutoPointer.new(ptr, C::Audio.method(:sfSound_destroy))) copy.instance_variable_set(:@buffer, @buffer) copy end |
#effect_processor=(callable) ⇒ Object
Install a real-time DSP filter. The callable is invoked from the CSFML audio thread once per audio frame batch with:
* `input` — Array<Float> of interleaved samples (signed [-1, 1])
* `channels` — Integer channel count (e.g. 2 for stereo)
and should return an Arraynil to remove an
installed processor.
CAVEAT: the callback runs on a real-time audio thread and is called every few milliseconds. Ruby + GVL is rarely fast enough for non-trivial DSP — expect glitches for anything heavier than a constant-gain or simple IIR. For real DSP, do it offline.
137 138 139 140 |
# File 'lib/sfml/audio/sound.rb', line 137 def effect_processor=(callable) @effect_cb = callable.nil? ? nil : Audio._build_effect_processor(callable) C::Audio.sfSound_setEffectProcessor(@handle, @effect_cb, nil) end |
#looping=(value) ⇒ Object
Toggle looping playback. With true, the sound restarts from
the start after every play-through.
149 150 151 152 |
# File 'lib/sfml/audio/sound.rb', line 149 def looping=(value) @looping = value ? true : false C::Audio.sfSound_setLooping(@handle, @looping) end |
#looping? ⇒ Boolean
true if the sound restarts after reaching the end.
143 144 145 |
# File 'lib/sfml/audio/sound.rb', line 143 def looping? @looping end |
#max_distance ⇒ Object
The distance beyond which the source is fully attenuated.
255 |
# File 'lib/sfml/audio/sound.rb', line 255 def max_distance = C::Audio.sfSound_getMaxDistance(@handle) |
#max_distance=(v) ⇒ Object
Set the max-distance — see #max_distance.
258 259 260 |
# File 'lib/sfml/audio/sound.rb', line 258 def max_distance=(v) C::Audio.sfSound_setMaxDistance(@handle, v.to_f) end |
#max_gain ⇒ Object
The upper gain bound — see #min_gain.
247 |
# File 'lib/sfml/audio/sound.rb', line 247 def max_gain = C::Audio.sfSound_getMaxGain(@handle) |
#max_gain=(v) ⇒ Object
Set the max-gain cap — see #max_gain.
250 251 252 |
# File 'lib/sfml/audio/sound.rb', line 250 def max_gain=(v) C::Audio.sfSound_setMaxGain(@handle, v.to_f) end |
#min_distance ⇒ Object
Distance below which volume is not attenuated.
201 |
# File 'lib/sfml/audio/sound.rb', line 201 def min_distance = C::Audio.sfSound_getMinDistance(@handle) |
#min_distance=(value) ⇒ Object
Set the min-distance — see #min_distance.
204 205 206 |
# File 'lib/sfml/audio/sound.rb', line 204 def min_distance=(value) C::Audio.sfSound_setMinDistance(@handle, value.to_f) end |
#min_gain ⇒ Object
Output gain clamping. min_gain floors the attenuated
gain; max_gain caps it. Useful when you want a sound to
always be at least faintly audible (or never louder than
the listener's local SFX volume).
239 |
# File 'lib/sfml/audio/sound.rb', line 239 def min_gain = C::Audio.sfSound_getMinGain(@handle) |
#min_gain=(v) ⇒ Object
Set the min-gain floor — see #min_gain.
242 243 244 |
# File 'lib/sfml/audio/sound.rb', line 242 def min_gain=(v) C::Audio.sfSound_setMinGain(@handle, v.to_f) end |
#pan ⇒ Object
Stereo pan in [-1.0, 1.0]: -1 = full left, 0 = centre, 1 = full right.
228 |
# File 'lib/sfml/audio/sound.rb', line 228 def pan = C::Audio.sfSound_getPan(@handle) |
#pan=(v) ⇒ Object
Set the stereo pan — see #pan.
231 232 233 |
# File 'lib/sfml/audio/sound.rb', line 231 def pan=(v) C::Audio.sfSound_setPan(@handle, v.to_f) end |
#pause ⇒ Object
Pause playback. #play resumes from this point; #stop rewinds.
42 43 |
# File 'lib/sfml/audio/sound.rb', line 42 def pause = C::Audio.sfSound_pause(@handle) # Stop playback and rewind to the start. |
#paused? ⇒ Boolean
Convenience predicate for status == :paused.
51 52 |
# File 'lib/sfml/audio/sound.rb', line 51 def paused? = status == :paused # Convenience predicate for `status == :stopped`. |
#pitch ⇒ Object
Pitch multiplier. 1.0 = normal, 2.0 = octave up, 0.5 = octave down. Also shifts playback duration proportionally.
164 |
# File 'lib/sfml/audio/sound.rb', line 164 def pitch = C::Audio.sfSound_getPitch(@handle) |
#pitch=(value) ⇒ Object
Set the pitch multiplier — see #pitch.
167 168 169 |
# File 'lib/sfml/audio/sound.rb', line 167 def pitch=(value) C::Audio.sfSound_setPitch(@handle, value.to_f) end |
#play ⇒ Object
Start playback. If the sound was paused, resumes from there. If it was already playing, restarts from the beginning.
40 41 |
# File 'lib/sfml/audio/sound.rb', line 40 def play = C::Audio.sfSound_play(@handle) # Pause playback. `#play` resumes from this point; `#stop` rewinds. |
#playing? ⇒ Boolean
Convenience predicate for status == :playing.
49 50 |
# File 'lib/sfml/audio/sound.rb', line 49 def = status == :playing # Convenience predicate for `status == :paused`. |
#playing_offset ⇒ Object
Current playback head as a SFML::Time. Reads from the underlying OpenAL source — only meaningful while the sound is playing or paused (not after #stop).
58 59 60 |
# File 'lib/sfml/audio/sound.rb', line 58 def Time.from_native(C::Audio.(@handle)) end |
#playing_offset=(value) ⇒ Object
Seek to value (a SFML::Time, or seconds as a Numeric). Works
while the sound is playing, paused, or stopped — calling #play
afterwards resumes from the new offset.
65 66 67 68 |
# File 'lib/sfml/audio/sound.rb', line 65 def (value) t = value.is_a?(Time) ? value : Time.seconds(value.to_f) C::Audio.(@handle, t.to_native) end |
#position ⇒ Object
---- 3D positional audio ----
Sounds have a 3D position; the SFML::Listener acts as the "ear".
Volume falls off with distance from min_distance outward, scaled
by attenuation (0 = no falloff, 1 = realistic, higher = sharper).
By default a Sound's position is in world coordinates; flip
relative_to_listener = true and the position becomes relative
to the listener — useful for "stuck to the camera" UI sounds.
For 2D games, set z = 0 and listener.position to your camera.
181 182 183 |
# File 'lib/sfml/audio/sound.rb', line 181 def position Vector3.from_native(C::Audio.sfSound_getPosition(@handle)) end |
#position=(value) ⇒ Object
Set the 3D position — accepts Vector3 or [x, y, z].
186 187 188 189 |
# File 'lib/sfml/audio/sound.rb', line 186 def position=(value) vec = value.is_a?(Vector3) ? value : Vector3.new(*value) C::Audio.sfSound_setPosition(@handle, vec.to_native_f) end |
#relative_to_listener=(value) ⇒ Object
Toggle listener-relative positioning.
214 215 216 |
# File 'lib/sfml/audio/sound.rb', line 214 def relative_to_listener=(value) C::Audio.sfSound_setRelativeToListener(@handle, value ? true : false) end |
#relative_to_listener? ⇒ Boolean
If true, #position is interpreted relative to the listener
(useful for HUD/UI sounds that should stay glued to the
camera).
211 |
# File 'lib/sfml/audio/sound.rb', line 211 def relative_to_listener? = C::Audio.sfSound_isRelativeToListener(@handle) |
#spatialization_enabled=(v) ⇒ Object
Toggle 3D spatialisation — see #spatialization_enabled?.
267 268 269 |
# File 'lib/sfml/audio/sound.rb', line 267 def spatialization_enabled=(v) C::Audio.sfSound_setSpatializationEnabled(@handle, v ? true : false) end |
#spatialization_enabled? ⇒ Boolean
Whether 3D-positional / Doppler / cone math is applied at mix time. Off → the sound plays as a simple stereo source.
264 |
# File 'lib/sfml/audio/sound.rb', line 264 def spatialization_enabled? = C::Audio.sfSound_isSpatializationEnabled(@handle) |
#status ⇒ Object
Playback state — one of :stopped, :paused, :playing.
47 48 |
# File 'lib/sfml/audio/sound.rb', line 47 def status = C::Audio::STATUSES[C::Audio.sfSound_getStatus(@handle)] # Convenience predicate for `status == :playing`. |
#stop ⇒ Object
Stop playback and rewind to the start.
44 |
# File 'lib/sfml/audio/sound.rb', line 44 def stop = C::Audio.sfSound_stop(@handle) |
#stopped? ⇒ Boolean
Convenience predicate for status == :stopped.
53 |
# File 'lib/sfml/audio/sound.rb', line 53 def stopped? = status == :stopped |
#velocity ⇒ Object
3D velocity in world units / second — used by the Doppler effect to shift pitch as the source approaches or recedes from the listener.
73 74 75 76 |
# File 'lib/sfml/audio/sound.rb', line 73 def velocity v = C::Audio.sfSound_getVelocity(@handle) Vector3.new(v[:x], v[:y], v[:z]) end |
#velocity=(value) ⇒ Object
Set the 3D velocity — accepts a Vector3 or [x, y, z].
79 80 81 82 83 84 |
# File 'lib/sfml/audio/sound.rb', line 79 def velocity=(value) vec = value.is_a?(Vector3) ? value : Vector3.new(*value) packed = C::System::Vector3f.new packed[:x] = vec.x.to_f; packed[:y] = vec.y.to_f; packed[:z] = vec.z.to_f C::Audio.sfSound_setVelocity(@handle, packed) end |