Class: SFML::Music

Inherits:
Object
  • Object
show all
Defined in:
lib/sfml/audio/music.rb

Overview

A streamed audio source. Use this for long tracks (background music) so the file isn’t loaded into memory all at once.

bgm = SFML::Music.load("assets/track.ogg", looping: true, volume: 60)
bgm.play

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_memory(bytes, **opts) ⇒ Object

Stream music from a Ruby String of bytes (an in-memory MP3, OGG, FLAC, …). Useful for embedded audio or downloaded tracks that bypass the disk. The bytes must outlive the Music object — SFML keeps a pointer into them.

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/sfml/audio/music.rb', line 19

def self.from_memory(bytes, **opts)
  raise ArgumentError, "expected a String, got #{bytes.class}" unless bytes.is_a?(String)

  buf = FFI::MemoryPointer.new(:uint8, bytes.bytesize)
  buf.write_bytes(bytes)
  ptr = C::Audio.sfMusic_createFromMemory(buf, bytes.bytesize)
  raise Error, "sfMusic_createFromMemory returned NULL — unsupported format?" if ptr.null?

  m = _wrap(ptr, opts)
  m.instance_variable_set(:@_memory_pin, buf)   # keep buffer alive
  m
end

.from_stream(io, **opts) ⇒ Object

Stream music straight from a Ruby IO-like object. CSFML reads the audio lazily on its decoding thread — keep the IO open until you stop the Music.

Raises:



35
36
37
38
39
40
41
42
43
44
# File 'lib/sfml/audio/music.rb', line 35

def self.from_stream(io, **opts)
  stream = SFML::InputStream.new(io)
  ptr = C::Audio.sfMusic_createFromStream(stream.to_ptr)
  raise Error, "sfMusic_createFromStream returned NULL — unsupported format?" if ptr.null?

  m = _wrap(ptr, opts)
  m.instance_variable_set(:@_stream_pin, stream)
  m.instance_variable_set(:@_io_pin, io)
  m
end

.load(path, **opts) ⇒ Object

Raises:



8
9
10
11
12
13
# File 'lib/sfml/audio/music.rb', line 8

def self.load(path, **opts)
  ptr = C::Audio.sfMusic_createFromFile(path.to_s)
  raise Error, "Could not load music from #{path.inspect}" if ptr.null?

  _wrap(ptr, opts)
end

Instance Method Details

#attenuationObject



166
# File 'lib/sfml/audio/music.rb', line 166

def attenuation = C::Audio.sfMusic_getAttenuation(@handle)

#attenuation=(value) ⇒ Object



168
169
170
# File 'lib/sfml/audio/music.rb', line 168

def attenuation=(value)
  C::Audio.sfMusic_setAttenuation(@handle, value.to_f)
end

#channel_countObject

—- Stream introspection —-



186
# File 'lib/sfml/audio/music.rb', line 186

def channel_count = C::Audio.sfMusic_getChannelCount(@handle)

#coneObject



113
114
115
# File 'lib/sfml/audio/music.rb', line 113

def cone
  SoundCone.from_native(C::Audio.sfMusic_getCone(@handle))
end

#cone=(value) ⇒ Object



117
118
119
120
121
122
123
124
125
126
# File 'lib/sfml/audio/music.rb', line 117

def cone=(value)
  cone =
    case value
    when SoundCone then value
    when Hash      then SoundCone.new(**value)
    else
      raise ArgumentError, "Music#cone= expects SoundCone or Hash; got #{value.class}"
    end
  C::Audio.sfMusic_setCone(@handle, cone.to_native)
end

#directionObject



101
102
103
104
# File 'lib/sfml/audio/music.rb', line 101

def direction
  v = C::Audio.sfMusic_getDirection(@handle)
  Vector3.new(v[:x], v[:y], v[:z])
end

#direction=(value) ⇒ Object



106
107
108
109
110
111
# File 'lib/sfml/audio/music.rb', line 106

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.sfMusic_setDirection(@handle, packed)
end

#directional_attenuation_factorObject



239
240
241
# File 'lib/sfml/audio/music.rb', line 239

def directional_attenuation_factor
  C::Audio.sfMusic_getDirectionalAttenuationFactor(@handle)
end

#directional_attenuation_factor=(v) ⇒ Object



243
244
245
# File 'lib/sfml/audio/music.rb', line 243

def directional_attenuation_factor=(v)
  C::Audio.sfMusic_setDirectionalAttenuationFactor(@handle, v.to_f)
end

#doppler_factorObject



98
# File 'lib/sfml/audio/music.rb', line 98

def doppler_factor    = C::Audio.sfMusic_getDopplerFactor(@handle)

#doppler_factor=(v) ⇒ Object



99
# File 'lib/sfml/audio/music.rb', line 99

def doppler_factor=(v) C::Audio.sfMusic_setDopplerFactor(@handle, v.to_f); end

#durationObject



68
# File 'lib/sfml/audio/music.rb', line 68

def duration = Time.from_native(C::Audio.sfMusic_getDuration(@handle))

#effect_processor=(callable) ⇒ Object

See Sound#effect_processor= — same audio-thread DSP callback.



129
130
131
132
# File 'lib/sfml/audio/music.rb', line 129

def effect_processor=(callable)
  @effect_cb = callable.nil? ? nil : Audio._build_effect_processor(callable)
  C::Audio.sfMusic_setEffectProcessor(@handle, @effect_cb, nil)
end

#loop_pointsObject

The portion of the track that loops when ‘looping = true`. Returns `[offset, length]` of `SFML::Time`s; defaults to the whole track. Set with `loop_points = [Time, Time]`.



192
193
194
195
# File 'lib/sfml/audio/music.rb', line 192

def loop_points
  span = C::Audio.sfMusic_getLoopPoints(@handle)
  [Time.from_native(span[:offset]), Time.from_native(span[:length])]
end

#loop_points=(value) ⇒ Object

Raises:

  • (ArgumentError)


197
198
199
200
201
202
203
204
205
# File 'lib/sfml/audio/music.rb', line 197

def loop_points=(value)
  offset_t, length_t = value
  raise ArgumentError, "expected [offset_time, length_time]" unless offset_t && length_t

  span = C::Audio::TimeSpan.new
  span[:offset][:microseconds] = offset_t.is_a?(Time) ? offset_t.microseconds : Time.seconds(offset_t.to_f).microseconds
  span[:length][:microseconds] = length_t.is_a?(Time) ? length_t.microseconds : Time.seconds(length_t.to_f).microseconds
  C::Audio.sfMusic_setLoopPoints(@handle, span)
end

#looping=(value) ⇒ Object



139
140
141
142
# File 'lib/sfml/audio/music.rb', line 139

def looping=(value)
  @looping = value ? true : false
  C::Audio.sfMusic_setLooping(@handle, @looping)
end

#looping?Boolean

Cached on the Ruby side; see Sound#looping? for the why.

Returns:

  • (Boolean)


135
136
137
# File 'lib/sfml/audio/music.rb', line 135

def looping?
  @looping
end

#max_distanceObject



227
# File 'lib/sfml/audio/music.rb', line 227

def max_distance = C::Audio.sfMusic_getMaxDistance(@handle)

#max_distance=(v) ⇒ Object



229
230
231
# File 'lib/sfml/audio/music.rb', line 229

def max_distance=(v)
  C::Audio.sfMusic_setMaxDistance(@handle, v.to_f)
end

#max_gainObject



221
# File 'lib/sfml/audio/music.rb', line 221

def max_gain = C::Audio.sfMusic_getMaxGain(@handle)

#max_gain=(v) ⇒ Object



223
224
225
# File 'lib/sfml/audio/music.rb', line 223

def max_gain=(v)
  C::Audio.sfMusic_setMaxGain(@handle, v.to_f)
end

#min_distanceObject



172
# File 'lib/sfml/audio/music.rb', line 172

def min_distance = C::Audio.sfMusic_getMinDistance(@handle)

#min_distance=(value) ⇒ Object



174
175
176
# File 'lib/sfml/audio/music.rb', line 174

def min_distance=(value)
  C::Audio.sfMusic_setMinDistance(@handle, value.to_f)
end

#min_gainObject



215
# File 'lib/sfml/audio/music.rb', line 215

def min_gain = C::Audio.sfMusic_getMinGain(@handle)

#min_gain=(v) ⇒ Object



217
218
219
# File 'lib/sfml/audio/music.rb', line 217

def min_gain=(v)
  C::Audio.sfMusic_setMinGain(@handle, v.to_f)
end

#panObject

—- 3D-audio extras (mirror of Sound’s) —-



209
# File 'lib/sfml/audio/music.rb', line 209

def pan = C::Audio.sfMusic_getPan(@handle)

#pan=(v) ⇒ Object



211
212
213
# File 'lib/sfml/audio/music.rb', line 211

def pan=(v)
  C::Audio.sfMusic_setPan(@handle, v.to_f)
end

#pauseObject



60
# File 'lib/sfml/audio/music.rb', line 60

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

#paused?Boolean

Returns:

  • (Boolean)


65
# File 'lib/sfml/audio/music.rb', line 65

def paused?  = status == :paused

#pitchObject



150
# File 'lib/sfml/audio/music.rb', line 150

def pitch = C::Audio.sfMusic_getPitch(@handle)

#pitch=(value) ⇒ Object



152
153
154
# File 'lib/sfml/audio/music.rb', line 152

def pitch=(value)
  C::Audio.sfMusic_setPitch(@handle, value.to_f)
end

#playObject



59
# File 'lib/sfml/audio/music.rb', line 59

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

#playing?Boolean

Returns:

  • (Boolean)


64
# File 'lib/sfml/audio/music.rb', line 64

def playing? = status == :playing

#playing_offsetObject

Current playback head as a SFML::Time. Reads from the underlying OpenAL source — only meaningful while the music is playing or paused (not after #stop).



73
74
75
# File 'lib/sfml/audio/music.rb', line 73

def playing_offset
  Time.from_native(C::Audio.sfMusic_getPlayingOffset(@handle))
end

#playing_offset=(value) ⇒ Object

Seek to ‘value` (a SFML::Time, or seconds as a Numeric). Works while the music is playing, paused, or stopped.



79
80
81
82
# File 'lib/sfml/audio/music.rb', line 79

def playing_offset=(value)
  t = value.is_a?(Time) ? value : Time.seconds(value.to_f)
  C::Audio.sfMusic_setPlayingOffset(@handle, t.to_native)
end

#positionObject

3D positional audio — see SFML::Sound for the why.



157
158
159
# File 'lib/sfml/audio/music.rb', line 157

def position
  Vector3.from_native(C::Audio.sfMusic_getPosition(@handle))
end

#position=(value) ⇒ Object



161
162
163
164
# File 'lib/sfml/audio/music.rb', line 161

def position=(value)
  vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
  C::Audio.sfMusic_setPosition(@handle, vec.to_native_f)
end

#relative_to_listener=(value) ⇒ Object



180
181
182
# File 'lib/sfml/audio/music.rb', line 180

def relative_to_listener=(value)
  C::Audio.sfMusic_setRelativeToListener(@handle, value ? true : false)
end

#relative_to_listener?Boolean

Returns:

  • (Boolean)


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

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

#sample_rateObject



187
# File 'lib/sfml/audio/music.rb', line 187

def sample_rate   = C::Audio.sfMusic_getSampleRate(@handle)

#spatialization_enabled=(v) ⇒ Object



235
236
237
# File 'lib/sfml/audio/music.rb', line 235

def spatialization_enabled=(v)
  C::Audio.sfMusic_setSpatializationEnabled(@handle, v ? true : false)
end

#spatialization_enabled?Boolean

Returns:

  • (Boolean)


233
# File 'lib/sfml/audio/music.rb', line 233

def spatialization_enabled? = C::Audio.sfMusic_isSpatializationEnabled(@handle)

#statusObject



63
# File 'lib/sfml/audio/music.rb', line 63

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

#stopObject



61
# File 'lib/sfml/audio/music.rb', line 61

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

#stopped?Boolean

Returns:

  • (Boolean)


66
# File 'lib/sfml/audio/music.rb', line 66

def stopped? = status == :stopped

#velocityObject

3D velocity, Doppler factor, direction, cone — see Sound for the same methods on the simpler buffered source.



86
87
88
89
# File 'lib/sfml/audio/music.rb', line 86

def velocity
  v = C::Audio.sfMusic_getVelocity(@handle)
  Vector3.new(v[:x], v[:y], v[:z])
end

#velocity=(value) ⇒ Object



91
92
93
94
95
96
# File 'lib/sfml/audio/music.rb', line 91

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.sfMusic_setVelocity(@handle, packed)
end

#volumeObject



144
# File 'lib/sfml/audio/music.rb', line 144

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

#volume=(value) ⇒ Object



146
147
148
# File 'lib/sfml/audio/music.rb', line 146

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