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
Returns the value of attribute buffer.
Instance Method Summary collapse
- #attenuation ⇒ Object
- #attenuation=(value) ⇒ Object
-
#cone ⇒ Object
Directional-attenuation cone — see SFML::SoundCone.
- #cone=(value) ⇒ Object
-
#direction ⇒ Object
The direction the sound’s cone points.
- #direction=(value) ⇒ Object
-
#doppler_factor ⇒ Object
Per-source Doppler scale.
- #doppler_factor=(v) ⇒ Object
-
#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
- #looping? ⇒ Boolean
- #min_distance ⇒ Object
- #min_distance=(value) ⇒ Object
- #pause ⇒ Object
- #paused? ⇒ Boolean
- #pitch ⇒ Object
- #pitch=(value) ⇒ Object
- #play ⇒ Object
- #playing? ⇒ Boolean
-
#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
- #relative_to_listener=(value) ⇒ Object
- #relative_to_listener? ⇒ Boolean
- #status ⇒ Object
- #stop ⇒ Object
- #stopped? ⇒ Boolean
-
#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
- #volume ⇒ Object
- #volume=(value) ⇒ Object
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 Error, "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
Returns the value of attribute buffer.
27 28 29 |
# File 'lib/sfml/audio/sound.rb', line 27 def buffer @buffer end |
Instance Method Details
#attenuation ⇒ Object
166 |
# File 'lib/sfml/audio/sound.rb', line 166 def attenuation = C::Audio.sfSound_getAttenuation(@handle) |
#attenuation=(value) ⇒ Object
168 169 170 |
# File 'lib/sfml/audio/sound.rb', line 168 def attenuation=(value) C::Audio.sfSound_setAttenuation(@handle, value.to_f) end |
#cone ⇒ Object
Directional-attenuation cone — see SFML::SoundCone.
94 95 96 |
# File 'lib/sfml/audio/sound.rb', line 94 def cone SoundCone.from_native(C::Audio.sfSound_getCone(@handle)) end |
#cone=(value) ⇒ Object
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/sfml/audio/sound.rb', line 98 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.
81 82 83 84 |
# File 'lib/sfml/audio/sound.rb', line 81 def direction v = C::Audio.sfSound_getDirection(@handle) Vector3.new(v[:x], v[:y], v[:z]) end |
#direction=(value) ⇒ Object
86 87 88 89 90 91 |
# File 'lib/sfml/audio/sound.rb', line 86 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 |
#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.
76 |
# File 'lib/sfml/audio/sound.rb', line 76 def doppler_factor = C::Audio.sfSound_getDopplerFactor(@handle) |
#doppler_factor=(v) ⇒ Object
77 |
# File 'lib/sfml/audio/sound.rb', line 77 def doppler_factor=(v) C::Audio.sfSound_setDopplerFactor(@handle, v.to_f); 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 Array<Float> of the same length (or shorter if the effect produces fewer frames). Pass ‘nil` 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.
121 122 123 124 |
# File 'lib/sfml/audio/sound.rb', line 121 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
130 131 132 133 |
# File 'lib/sfml/audio/sound.rb', line 130 def looping=(value) @looping = value ? true : false C::Audio.sfSound_setLooping(@handle, @looping) end |
#looping? ⇒ Boolean
126 127 128 |
# File 'lib/sfml/audio/sound.rb', line 126 def looping? @looping end |
#min_distance ⇒ Object
172 |
# File 'lib/sfml/audio/sound.rb', line 172 def min_distance = C::Audio.sfSound_getMinDistance(@handle) |
#min_distance=(value) ⇒ Object
174 175 176 |
# File 'lib/sfml/audio/sound.rb', line 174 def min_distance=(value) C::Audio.sfSound_setMinDistance(@handle, value.to_f) end |
#pause ⇒ Object
36 |
# File 'lib/sfml/audio/sound.rb', line 36 def pause = C::Audio.sfSound_pause(@handle) |
#paused? ⇒ Boolean
41 |
# File 'lib/sfml/audio/sound.rb', line 41 def paused? = status == :paused |
#pitch ⇒ Object
141 |
# File 'lib/sfml/audio/sound.rb', line 141 def pitch = C::Audio.sfSound_getPitch(@handle) |
#pitch=(value) ⇒ Object
143 144 145 |
# File 'lib/sfml/audio/sound.rb', line 143 def pitch=(value) C::Audio.sfSound_setPitch(@handle, value.to_f) end |
#play ⇒ Object
35 |
# File 'lib/sfml/audio/sound.rb', line 35 def play = C::Audio.sfSound_play(@handle) |
#playing? ⇒ Boolean
40 |
# File 'lib/sfml/audio/sound.rb', line 40 def = status == :playing |
#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).
47 48 49 |
# File 'lib/sfml/audio/sound.rb', line 47 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.
54 55 56 57 |
# File 'lib/sfml/audio/sound.rb', line 54 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.
157 158 159 |
# File 'lib/sfml/audio/sound.rb', line 157 def position Vector3.from_native(C::Audio.sfSound_getPosition(@handle)) end |
#position=(value) ⇒ Object
161 162 163 164 |
# File 'lib/sfml/audio/sound.rb', line 161 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
180 181 182 |
# File 'lib/sfml/audio/sound.rb', line 180 def relative_to_listener=(value) C::Audio.sfSound_setRelativeToListener(@handle, value ? true : false) end |
#relative_to_listener? ⇒ Boolean
178 |
# File 'lib/sfml/audio/sound.rb', line 178 def relative_to_listener? = C::Audio.sfSound_isRelativeToListener(@handle) |
#status ⇒ Object
39 |
# File 'lib/sfml/audio/sound.rb', line 39 def status = C::Audio::STATUSES[C::Audio.sfSound_getStatus(@handle)] |
#stop ⇒ Object
37 |
# File 'lib/sfml/audio/sound.rb', line 37 def stop = C::Audio.sfSound_stop(@handle) |
#stopped? ⇒ Boolean
42 |
# File 'lib/sfml/audio/sound.rb', line 42 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.
62 63 64 65 |
# File 'lib/sfml/audio/sound.rb', line 62 def velocity v = C::Audio.sfSound_getVelocity(@handle) Vector3.new(v[:x], v[:y], v[:z]) end |
#velocity=(value) ⇒ Object
67 68 69 70 71 72 |
# File 'lib/sfml/audio/sound.rb', line 67 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 |