Class: SFML::Sound

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(buffer, volume: 100.0, pitch: 1.0, looping: false) ⇒ Sound

Returns a new instance of Sound.

Raises:

  • (ArgumentError)


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

#bufferObject

Returns the value of attribute buffer.



27
28
29
# File 'lib/sfml/audio/sound.rb', line 27

def buffer
  @buffer
end

Instance Method Details

#attenuationObject



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

#coneObject

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

#directionObject

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_factorObject

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

Returns:

  • (Boolean)


126
127
128
# File 'lib/sfml/audio/sound.rb', line 126

def looping?
  @looping
end

#min_distanceObject



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

#pauseObject



36
# File 'lib/sfml/audio/sound.rb', line 36

def pause  = C::Audio.sfSound_pause(@handle)

#paused?Boolean

Returns:

  • (Boolean)


41
# File 'lib/sfml/audio/sound.rb', line 41

def paused?     = status == :paused

#pitchObject



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

#playObject



35
# File 'lib/sfml/audio/sound.rb', line 35

def play   = C::Audio.sfSound_play(@handle)

#playing?Boolean

Returns:

  • (Boolean)


40
# File 'lib/sfml/audio/sound.rb', line 40

def playing?    = status == :playing

#playing_offsetObject

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 playing_offset
  Time.from_native(C::Audio.sfSound_getPlayingOffset(@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 playing_offset=(value)
  t = value.is_a?(Time) ? value : Time.seconds(value.to_f)
  C::Audio.sfSound_setPlayingOffset(@handle, t.to_native)
end

#positionObject

—- 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

Returns:

  • (Boolean)


178
# File 'lib/sfml/audio/sound.rb', line 178

def relative_to_listener? = C::Audio.sfSound_isRelativeToListener(@handle)

#statusObject



39
# File 'lib/sfml/audio/sound.rb', line 39

def status      = C::Audio::STATUSES[C::Audio.sfSound_getStatus(@handle)]

#stopObject



37
# File 'lib/sfml/audio/sound.rb', line 37

def stop   = C::Audio.sfSound_stop(@handle)

#stopped?Boolean

Returns:

  • (Boolean)


42
# File 'lib/sfml/audio/sound.rb', line 42

def stopped?    = status == :stopped

#velocityObject

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

#volumeObject



135
# File 'lib/sfml/audio/sound.rb', line 135

def volume      = C::Audio.sfSound_getVolume(@handle)

#volume=(value) ⇒ Object



137
138
139
# File 'lib/sfml/audio/sound.rb', line 137

def volume=(value)
  C::Audio.sfSound_setVolume(@handle, value.to_f)
end