ruby-sfml 3.0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +101 -0
- data/LICENSE.txt +21 -0
- data/README.md +245 -0
- data/ext/ruby-sfml/extconf.rb +69 -0
- data/lib/sfml/assets/fonts/DejaVuSans.LICENSE.txt +78 -0
- data/lib/sfml/assets/fonts/DejaVuSans.ttf +0 -0
- data/lib/sfml/assets.rb +121 -0
- data/lib/sfml/audio/listener.rb +55 -0
- data/lib/sfml/audio/music.rb +88 -0
- data/lib/sfml/audio/sound.rb +102 -0
- data/lib/sfml/audio/sound_buffer.rb +38 -0
- data/lib/sfml/audio/sound_buffer_recorder.rb +71 -0
- data/lib/sfml/audio/sound_recorder.rb +30 -0
- data/lib/sfml/c/audio.rb +106 -0
- data/lib/sfml/c/graphics.rb +425 -0
- data/lib/sfml/c/network.rb +79 -0
- data/lib/sfml/c/system.rb +43 -0
- data/lib/sfml/c/window.rb +186 -0
- data/lib/sfml/c.rb +72 -0
- data/lib/sfml/game.rb +101 -0
- data/lib/sfml/graphics/blend_mode.rb +108 -0
- data/lib/sfml/graphics/circle_shape.rb +67 -0
- data/lib/sfml/graphics/color.rb +89 -0
- data/lib/sfml/graphics/convex_shape.rb +82 -0
- data/lib/sfml/graphics/font.rb +67 -0
- data/lib/sfml/graphics/image.rb +125 -0
- data/lib/sfml/graphics/rectangle_shape.rb +62 -0
- data/lib/sfml/graphics/render_states.rb +56 -0
- data/lib/sfml/graphics/render_target.rb +146 -0
- data/lib/sfml/graphics/render_texture.rb +72 -0
- data/lib/sfml/graphics/render_window.rb +154 -0
- data/lib/sfml/graphics/shader.rb +132 -0
- data/lib/sfml/graphics/sprite.rb +75 -0
- data/lib/sfml/graphics/text.rb +144 -0
- data/lib/sfml/graphics/texture.rb +79 -0
- data/lib/sfml/graphics/transform.rb +150 -0
- data/lib/sfml/graphics/transformable.rb +74 -0
- data/lib/sfml/graphics/vertex.rb +53 -0
- data/lib/sfml/graphics/vertex_array.rb +114 -0
- data/lib/sfml/graphics/view.rb +126 -0
- data/lib/sfml/network/ip_address.rb +67 -0
- data/lib/sfml/network/tcp_listener.rb +61 -0
- data/lib/sfml/network/tcp_socket.rb +74 -0
- data/lib/sfml/network/udp_socket.rb +71 -0
- data/lib/sfml/system/clock.rb +44 -0
- data/lib/sfml/system/rect.rb +64 -0
- data/lib/sfml/system/time.rb +48 -0
- data/lib/sfml/system/vector2.rb +66 -0
- data/lib/sfml/system/vector3.rb +63 -0
- data/lib/sfml/version.rb +19 -0
- data/lib/sfml/window/clipboard.rb +38 -0
- data/lib/sfml/window/cursor.rb +68 -0
- data/lib/sfml/window/event.rb +133 -0
- data/lib/sfml/window/joystick.rb +90 -0
- data/lib/sfml/window/keyboard.rb +60 -0
- data/lib/sfml/window/mouse.rb +71 -0
- data/lib/sfml/window/video_mode.rb +37 -0
- data/lib/sfml/window/window.rb +149 -0
- data/lib/sfml.rb +98 -0
- data/ruby-sfml.gemspec +38 -0
- metadata +163 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# The "ear" — a global, single-instance object that defines from
|
|
3
|
+
# where the player hears the world. Sounds positioned via Sound#position=
|
|
4
|
+
# attenuate based on their distance from this point.
|
|
5
|
+
#
|
|
6
|
+
# SFML::Listener.position = [400, 300, 0] # follow your camera
|
|
7
|
+
# SFML::Listener.global_volume = 80 # 0..100, master gain
|
|
8
|
+
#
|
|
9
|
+
# For 2D games keep z = 0 and treat x, y as world coords. For
|
|
10
|
+
# first-person stuff also set Listener.direction to point along the
|
|
11
|
+
# camera forward.
|
|
12
|
+
module Listener
|
|
13
|
+
module_function
|
|
14
|
+
|
|
15
|
+
# Master volume in the range [0, 100]. Affects all sounds, music, etc.
|
|
16
|
+
def global_volume
|
|
17
|
+
C::Audio.sfListener_getGlobalVolume
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def global_volume=(value)
|
|
21
|
+
C::Audio.sfListener_setGlobalVolume(value.to_f)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def position
|
|
25
|
+
Vector3.from_native(C::Audio.sfListener_getPosition)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def position=(value)
|
|
29
|
+
vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
|
|
30
|
+
C::Audio.sfListener_setPosition(vec.to_native_f)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# The forward direction of the listener (unit-length, doesn't have to be).
|
|
34
|
+
# Default: (0, 0, -1) — looking into the screen.
|
|
35
|
+
def direction
|
|
36
|
+
Vector3.from_native(C::Audio.sfListener_getDirection)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def direction=(value)
|
|
40
|
+
vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
|
|
41
|
+
C::Audio.sfListener_setDirection(vec.to_native_f)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# The "up" direction. Default: (0, 1, 0). Together with `direction`
|
|
45
|
+
# it determines listener orientation for stereo panning.
|
|
46
|
+
def up_vector
|
|
47
|
+
Vector3.from_native(C::Audio.sfListener_getUpVector)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def up_vector=(value)
|
|
51
|
+
vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
|
|
52
|
+
C::Audio.sfListener_setUpVector(vec.to_native_f)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# A streamed audio source. Use this for long tracks (background music) so
|
|
3
|
+
# the file isn't loaded into memory all at once.
|
|
4
|
+
#
|
|
5
|
+
# bgm = SFML::Music.load("assets/track.ogg", looping: true, volume: 60)
|
|
6
|
+
# bgm.play
|
|
7
|
+
class Music
|
|
8
|
+
def self.load(path, **opts)
|
|
9
|
+
ptr = C::Audio.sfMusic_createFromFile(path.to_s)
|
|
10
|
+
raise Error, "Could not load music from #{path.inspect}" if ptr.null?
|
|
11
|
+
|
|
12
|
+
m = allocate
|
|
13
|
+
m.send(:_take_ownership, ptr)
|
|
14
|
+
m.instance_variable_set(:@looping, false)
|
|
15
|
+
m.volume = opts[:volume] if opts.key?(:volume)
|
|
16
|
+
m.pitch = opts[:pitch] if opts.key?(:pitch)
|
|
17
|
+
m.looping = opts[:looping] if opts.key?(:looping)
|
|
18
|
+
m
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def play = C::Audio.sfMusic_play(@handle)
|
|
22
|
+
def pause = C::Audio.sfMusic_pause(@handle)
|
|
23
|
+
def stop = C::Audio.sfMusic_stop(@handle)
|
|
24
|
+
|
|
25
|
+
def status = C::Audio::STATUSES[C::Audio.sfMusic_getStatus(@handle)]
|
|
26
|
+
def playing? = status == :playing
|
|
27
|
+
def paused? = status == :paused
|
|
28
|
+
def stopped? = status == :stopped
|
|
29
|
+
|
|
30
|
+
def duration = Time.from_native(C::Audio.sfMusic_getDuration(@handle))
|
|
31
|
+
|
|
32
|
+
# Cached on the Ruby side; see Sound#looping? for the why.
|
|
33
|
+
def looping?
|
|
34
|
+
@looping
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def looping=(value)
|
|
38
|
+
@looping = value ? true : false
|
|
39
|
+
C::Audio.sfMusic_setLooping(@handle, @looping)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def volume = C::Audio.sfMusic_getVolume(@handle)
|
|
43
|
+
|
|
44
|
+
def volume=(value)
|
|
45
|
+
C::Audio.sfMusic_setVolume(@handle, value.to_f)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def pitch = C::Audio.sfMusic_getPitch(@handle)
|
|
49
|
+
|
|
50
|
+
def pitch=(value)
|
|
51
|
+
C::Audio.sfMusic_setPitch(@handle, value.to_f)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# 3D positional audio — see SFML::Sound for the why.
|
|
55
|
+
def position
|
|
56
|
+
Vector3.from_native(C::Audio.sfMusic_getPosition(@handle))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def position=(value)
|
|
60
|
+
vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
|
|
61
|
+
C::Audio.sfMusic_setPosition(@handle, vec.to_native_f)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def attenuation = C::Audio.sfMusic_getAttenuation(@handle)
|
|
65
|
+
|
|
66
|
+
def attenuation=(value)
|
|
67
|
+
C::Audio.sfMusic_setAttenuation(@handle, value.to_f)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def min_distance = C::Audio.sfMusic_getMinDistance(@handle)
|
|
71
|
+
|
|
72
|
+
def min_distance=(value)
|
|
73
|
+
C::Audio.sfMusic_setMinDistance(@handle, value.to_f)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def relative_to_listener? = C::Audio.sfMusic_isRelativeToListener(@handle)
|
|
77
|
+
|
|
78
|
+
def relative_to_listener=(value)
|
|
79
|
+
C::Audio.sfMusic_setRelativeToListener(@handle, value ? true : false)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def _take_ownership(ptr)
|
|
85
|
+
@handle = FFI::AutoPointer.new(ptr, C::Audio.method(:sfMusic_destroy))
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# A short sound that plays from a SoundBuffer held entirely in memory.
|
|
3
|
+
# Cheap to create, suitable for game SFX (blips, hits, footsteps).
|
|
4
|
+
#
|
|
5
|
+
# buffer = SFML::SoundBuffer.load("blip.wav")
|
|
6
|
+
# sound = SFML::Sound.new(buffer, volume: 80, pitch: 1.2, looping: true)
|
|
7
|
+
# sound.play
|
|
8
|
+
class Sound
|
|
9
|
+
def initialize(buffer, volume: 100.0, pitch: 1.0, looping: false)
|
|
10
|
+
raise ArgumentError, "Sound requires a SFML::SoundBuffer" unless buffer.is_a?(SoundBuffer)
|
|
11
|
+
|
|
12
|
+
ptr = C::Audio.sfSound_create(buffer.handle)
|
|
13
|
+
raise Error, "sfSound_create returned NULL" if ptr.null?
|
|
14
|
+
@handle = FFI::AutoPointer.new(ptr, C::Audio.method(:sfSound_destroy))
|
|
15
|
+
@buffer = buffer # keep alive
|
|
16
|
+
# @looping mirrors the loop flag because SFML 3's isLooping reads
|
|
17
|
+
# through an OpenAL source that may be unallocated on systems
|
|
18
|
+
# without an audio device (some CI runners). Caching on the Ruby
|
|
19
|
+
# side keeps observable behaviour deterministic regardless.
|
|
20
|
+
@looping = false
|
|
21
|
+
|
|
22
|
+
self.volume = volume
|
|
23
|
+
self.pitch = pitch
|
|
24
|
+
self.looping = looping
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :buffer
|
|
28
|
+
|
|
29
|
+
def buffer=(new_buffer)
|
|
30
|
+
raise ArgumentError, "Sound#buffer= requires a SFML::SoundBuffer" unless new_buffer.is_a?(SoundBuffer)
|
|
31
|
+
C::Audio.sfSound_setBuffer(@handle, new_buffer.handle)
|
|
32
|
+
@buffer = new_buffer
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def play = C::Audio.sfSound_play(@handle)
|
|
36
|
+
def pause = C::Audio.sfSound_pause(@handle)
|
|
37
|
+
def stop = C::Audio.sfSound_stop(@handle)
|
|
38
|
+
|
|
39
|
+
def status = C::Audio::STATUSES[C::Audio.sfSound_getStatus(@handle)]
|
|
40
|
+
def playing? = status == :playing
|
|
41
|
+
def paused? = status == :paused
|
|
42
|
+
def stopped? = status == :stopped
|
|
43
|
+
|
|
44
|
+
def looping?
|
|
45
|
+
@looping
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def looping=(value)
|
|
49
|
+
@looping = value ? true : false
|
|
50
|
+
C::Audio.sfSound_setLooping(@handle, @looping)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def volume = C::Audio.sfSound_getVolume(@handle)
|
|
54
|
+
|
|
55
|
+
def volume=(value)
|
|
56
|
+
C::Audio.sfSound_setVolume(@handle, value.to_f)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def pitch = C::Audio.sfSound_getPitch(@handle)
|
|
60
|
+
|
|
61
|
+
def pitch=(value)
|
|
62
|
+
C::Audio.sfSound_setPitch(@handle, value.to_f)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# ---- 3D positional audio ----
|
|
66
|
+
#
|
|
67
|
+
# Sounds have a 3D position; the SFML::Listener acts as the "ear".
|
|
68
|
+
# Volume falls off with distance from min_distance outward, scaled
|
|
69
|
+
# by attenuation (0 = no falloff, 1 = realistic, higher = sharper).
|
|
70
|
+
# By default a Sound's position is in world coordinates; flip
|
|
71
|
+
# `relative_to_listener = true` and the position becomes relative
|
|
72
|
+
# to the listener — useful for "stuck to the camera" UI sounds.
|
|
73
|
+
#
|
|
74
|
+
# For 2D games, set z = 0 and listener.position to your camera.
|
|
75
|
+
def position
|
|
76
|
+
Vector3.from_native(C::Audio.sfSound_getPosition(@handle))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def position=(value)
|
|
80
|
+
vec = value.is_a?(Vector3) ? value : Vector3.new(*value)
|
|
81
|
+
C::Audio.sfSound_setPosition(@handle, vec.to_native_f)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def attenuation = C::Audio.sfSound_getAttenuation(@handle)
|
|
85
|
+
|
|
86
|
+
def attenuation=(value)
|
|
87
|
+
C::Audio.sfSound_setAttenuation(@handle, value.to_f)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def min_distance = C::Audio.sfSound_getMinDistance(@handle)
|
|
91
|
+
|
|
92
|
+
def min_distance=(value)
|
|
93
|
+
C::Audio.sfSound_setMinDistance(@handle, value.to_f)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def relative_to_listener? = C::Audio.sfSound_isRelativeToListener(@handle)
|
|
97
|
+
|
|
98
|
+
def relative_to_listener=(value)
|
|
99
|
+
C::Audio.sfSound_setRelativeToListener(@handle, value ? true : false)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# Decoded audio data held in memory. Use it to back one or more Sound
|
|
3
|
+
# instances. Loaded from .wav, .ogg, .flac, .mp3 (depends on CSFML build).
|
|
4
|
+
#
|
|
5
|
+
# buffer = SFML::SoundBuffer.load("assets/blip.wav")
|
|
6
|
+
# sound = SFML::Sound.new(buffer)
|
|
7
|
+
# sound.play
|
|
8
|
+
class SoundBuffer
|
|
9
|
+
def self.load(path)
|
|
10
|
+
ptr = C::Audio.sfSoundBuffer_createFromFile(path.to_s)
|
|
11
|
+
raise Error, "Could not load sound buffer from #{path.inspect}" if ptr.null?
|
|
12
|
+
buf = allocate
|
|
13
|
+
buf.send(:_take_ownership, ptr)
|
|
14
|
+
buf
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def duration = Time.from_native(C::Audio.sfSoundBuffer_getDuration(@handle))
|
|
18
|
+
def sample_rate = C::Audio.sfSoundBuffer_getSampleRate(@handle)
|
|
19
|
+
def channel_count = C::Audio.sfSoundBuffer_getChannelCount(@handle)
|
|
20
|
+
|
|
21
|
+
# Write the buffer out to disk. Format is inferred from the file
|
|
22
|
+
# extension (.wav / .ogg / .flac, depends on what CSFML was built
|
|
23
|
+
# with).
|
|
24
|
+
def save(path)
|
|
25
|
+
ok = C::Audio.sfSoundBuffer_saveToFile(@handle, path.to_s)
|
|
26
|
+
raise Error, "could not save SoundBuffer to #{path.inspect}" unless ok
|
|
27
|
+
path
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :handle # :nodoc:
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def _take_ownership(ptr)
|
|
35
|
+
@handle = FFI::AutoPointer.new(ptr, C::Audio.method(:sfSoundBuffer_destroy))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# Records audio from the system input (microphone) directly into a
|
|
3
|
+
# SoundBuffer. Quickest path for a "record audio" feature — start,
|
|
4
|
+
# speak, stop, save:
|
|
5
|
+
#
|
|
6
|
+
# recorder = SFML::SoundBufferRecorder.new
|
|
7
|
+
# recorder.start(sample_rate: 44100)
|
|
8
|
+
# sleep 3
|
|
9
|
+
# recorder.stop
|
|
10
|
+
# recorder.buffer.save("memo.wav")
|
|
11
|
+
#
|
|
12
|
+
# Recording requires a working input device; SFML::SoundRecorder.available?
|
|
13
|
+
# tells you whether one is present before you start.
|
|
14
|
+
class SoundBufferRecorder
|
|
15
|
+
def initialize
|
|
16
|
+
ptr = C::Audio.sfSoundBufferRecorder_create
|
|
17
|
+
raise Error, "sfSoundBufferRecorder_create returned NULL" if ptr.null?
|
|
18
|
+
@handle = FFI::AutoPointer.new(ptr, C::Audio.method(:sfSoundBufferRecorder_destroy))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Begin capturing samples at the given sample rate. Returns true on
|
|
22
|
+
# success, false if the device couldn't be opened.
|
|
23
|
+
def start(sample_rate: 44_100)
|
|
24
|
+
C::Audio.sfSoundBufferRecorder_start(@handle, Integer(sample_rate))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def stop
|
|
28
|
+
C::Audio.sfSoundBufferRecorder_stop(@handle)
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sample_rate
|
|
33
|
+
C::Audio.sfSoundBufferRecorder_getSampleRate(@handle)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def channel_count
|
|
37
|
+
C::Audio.sfSoundBufferRecorder_getChannelCount(@handle)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def channel_count=(value)
|
|
41
|
+
C::Audio.sfSoundBufferRecorder_setChannelCount(@handle, Integer(value))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# The captured audio so far. Returned as a borrowed SoundBuffer
|
|
45
|
+
# owned by the recorder — copy it (via #save or by feeding to a
|
|
46
|
+
# Sound) before destroying the recorder, or build a Sound that
|
|
47
|
+
# outlives the recorder via the buffer's data.
|
|
48
|
+
def buffer
|
|
49
|
+
ptr = C::Audio.sfSoundBufferRecorder_getBuffer(@handle)
|
|
50
|
+
raise Error, "sfSoundBufferRecorder_getBuffer returned NULL" if ptr.null?
|
|
51
|
+
# Borrowed — recorder owns the underlying sf::SoundBuffer.
|
|
52
|
+
buf = SoundBuffer.allocate
|
|
53
|
+
buf.instance_variable_set(:@handle, ptr)
|
|
54
|
+
buf
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Currently selected input device name (or nil).
|
|
58
|
+
def device
|
|
59
|
+
name = C::Audio.sfSoundBufferRecorder_getDevice(@handle)
|
|
60
|
+
name unless name.nil? || name.empty?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def device=(name)
|
|
64
|
+
ok = C::Audio.sfSoundBufferRecorder_setDevice(@handle, name.to_s)
|
|
65
|
+
raise Error, "could not select recording device #{name.inspect}" unless ok
|
|
66
|
+
name
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
attr_reader :handle # :nodoc:
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
# Static helpers for audio capture. Use SFML::SoundBufferRecorder
|
|
3
|
+
# to actually record; these tell you what hardware is available.
|
|
4
|
+
#
|
|
5
|
+
# SFML::SoundRecorder.available? #=> true / false
|
|
6
|
+
# SFML::SoundRecorder.devices #=> ["alsa_input.pci-...", ...]
|
|
7
|
+
# SFML::SoundRecorder.default_device #=> "alsa_input.pci-..."
|
|
8
|
+
module SoundRecorder
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Is at least one audio input device present on the host?
|
|
12
|
+
def available?
|
|
13
|
+
C::Audio.sfSoundRecorder_isAvailable
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def default_device
|
|
17
|
+
C::Audio.sfSoundRecorder_getDefaultDevice
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# All input devices the OS exposes to SFML, as an Array of String
|
|
21
|
+
# names. Pass any of them to SoundBufferRecorder#device= to switch.
|
|
22
|
+
def devices
|
|
23
|
+
count_buf = FFI::MemoryPointer.new(:size_t)
|
|
24
|
+
array_ptr = C::Audio.sfSoundRecorder_getAvailableDevices(count_buf)
|
|
25
|
+
n = count_buf.read(:size_t)
|
|
26
|
+
return [] if array_ptr.null? || n.zero?
|
|
27
|
+
array_ptr.read_array_of_pointer(n).map { |p| p.read_string }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/sfml/c/audio.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
module SFML
|
|
2
|
+
module C
|
|
3
|
+
module Audio
|
|
4
|
+
extend FFI::Library
|
|
5
|
+
|
|
6
|
+
ffi_lib LIB_CANDIDATES[:audio]
|
|
7
|
+
|
|
8
|
+
typedef :pointer, :sound_buffer_t
|
|
9
|
+
typedef :pointer, :sound_t
|
|
10
|
+
typedef :pointer, :music_t
|
|
11
|
+
|
|
12
|
+
# sfSoundStatus = { sfStopped, sfPaused, sfPlaying } in that order.
|
|
13
|
+
STATUSES = %i[stopped paused playing].freeze
|
|
14
|
+
|
|
15
|
+
# ---- SoundBuffer ----
|
|
16
|
+
attach_function :sfSoundBuffer_createFromFile, [:string], :sound_buffer_t
|
|
17
|
+
attach_function :sfSoundBuffer_destroy, [:sound_buffer_t], :void
|
|
18
|
+
attach_function :sfSoundBuffer_saveToFile, [:sound_buffer_t, :string], :bool
|
|
19
|
+
attach_function :sfSoundBuffer_getDuration, [:sound_buffer_t], System::Time.by_value
|
|
20
|
+
attach_function :sfSoundBuffer_getSampleRate, [:sound_buffer_t], :uint32
|
|
21
|
+
attach_function :sfSoundBuffer_getChannelCount,[:sound_buffer_t], :uint32
|
|
22
|
+
|
|
23
|
+
# ---- Sound ----
|
|
24
|
+
attach_function :sfSound_create, [:sound_buffer_t], :sound_t
|
|
25
|
+
attach_function :sfSound_destroy, [:sound_t], :void
|
|
26
|
+
attach_function :sfSound_play, [:sound_t], :void
|
|
27
|
+
attach_function :sfSound_pause, [:sound_t], :void
|
|
28
|
+
attach_function :sfSound_stop, [:sound_t], :void
|
|
29
|
+
attach_function :sfSound_setBuffer, [:sound_t, :sound_buffer_t], :void
|
|
30
|
+
attach_function :sfSound_setLooping, [:sound_t, :bool], :void
|
|
31
|
+
attach_function :sfSound_isLooping, [:sound_t], :bool
|
|
32
|
+
attach_function :sfSound_getStatus, [:sound_t], :int
|
|
33
|
+
attach_function :sfSound_setVolume, [:sound_t, :float], :void
|
|
34
|
+
attach_function :sfSound_getVolume, [:sound_t], :float
|
|
35
|
+
attach_function :sfSound_setPitch, [:sound_t, :float], :void
|
|
36
|
+
attach_function :sfSound_getPitch, [:sound_t], :float
|
|
37
|
+
|
|
38
|
+
# 3D positional audio
|
|
39
|
+
attach_function :sfSound_setPosition, [:sound_t, System::Vector3f.by_value], :void
|
|
40
|
+
attach_function :sfSound_getPosition, [:sound_t], System::Vector3f.by_value
|
|
41
|
+
attach_function :sfSound_setMinDistance, [:sound_t, :float], :void
|
|
42
|
+
attach_function :sfSound_getMinDistance, [:sound_t], :float
|
|
43
|
+
attach_function :sfSound_setAttenuation, [:sound_t, :float], :void
|
|
44
|
+
attach_function :sfSound_getAttenuation, [:sound_t], :float
|
|
45
|
+
attach_function :sfSound_setRelativeToListener, [:sound_t, :bool], :void
|
|
46
|
+
attach_function :sfSound_isRelativeToListener, [:sound_t], :bool
|
|
47
|
+
|
|
48
|
+
# ---- Music ----
|
|
49
|
+
attach_function :sfMusic_createFromFile, [:string], :music_t
|
|
50
|
+
attach_function :sfMusic_destroy, [:music_t], :void
|
|
51
|
+
attach_function :sfMusic_play, [:music_t], :void
|
|
52
|
+
attach_function :sfMusic_pause, [:music_t], :void
|
|
53
|
+
attach_function :sfMusic_stop, [:music_t], :void
|
|
54
|
+
attach_function :sfMusic_setLooping, [:music_t, :bool], :void
|
|
55
|
+
attach_function :sfMusic_isLooping, [:music_t], :bool
|
|
56
|
+
attach_function :sfMusic_getStatus, [:music_t], :int
|
|
57
|
+
attach_function :sfMusic_setVolume, [:music_t, :float], :void
|
|
58
|
+
attach_function :sfMusic_getVolume, [:music_t], :float
|
|
59
|
+
attach_function :sfMusic_setPitch, [:music_t, :float], :void
|
|
60
|
+
attach_function :sfMusic_getPitch, [:music_t], :float
|
|
61
|
+
attach_function :sfMusic_getDuration, [:music_t], System::Time.by_value
|
|
62
|
+
|
|
63
|
+
attach_function :sfMusic_setPosition, [:music_t, System::Vector3f.by_value], :void
|
|
64
|
+
attach_function :sfMusic_getPosition, [:music_t], System::Vector3f.by_value
|
|
65
|
+
attach_function :sfMusic_setMinDistance, [:music_t, :float], :void
|
|
66
|
+
attach_function :sfMusic_getMinDistance, [:music_t], :float
|
|
67
|
+
attach_function :sfMusic_setAttenuation, [:music_t, :float], :void
|
|
68
|
+
attach_function :sfMusic_getAttenuation, [:music_t], :float
|
|
69
|
+
attach_function :sfMusic_setRelativeToListener, [:music_t, :bool], :void
|
|
70
|
+
attach_function :sfMusic_isRelativeToListener, [:music_t], :bool
|
|
71
|
+
|
|
72
|
+
# ---- SoundBufferRecorder ----
|
|
73
|
+
# The simple "record into a SoundBuffer" path. Raw sfSoundRecorder
|
|
74
|
+
# (callback-based) and sfSoundStream (custom audio source via
|
|
75
|
+
# callbacks) need Ruby callbacks running on the SFML audio thread —
|
|
76
|
+
# not worth the complexity for a niche feature.
|
|
77
|
+
typedef :pointer, :sound_buffer_recorder_t
|
|
78
|
+
|
|
79
|
+
attach_function :sfSoundBufferRecorder_create, [], :sound_buffer_recorder_t
|
|
80
|
+
attach_function :sfSoundBufferRecorder_destroy, [:sound_buffer_recorder_t], :void
|
|
81
|
+
attach_function :sfSoundBufferRecorder_start, [:sound_buffer_recorder_t, :uint32], :bool
|
|
82
|
+
attach_function :sfSoundBufferRecorder_stop, [:sound_buffer_recorder_t], :void
|
|
83
|
+
attach_function :sfSoundBufferRecorder_getSampleRate, [:sound_buffer_recorder_t], :uint32
|
|
84
|
+
attach_function :sfSoundBufferRecorder_getBuffer, [:sound_buffer_recorder_t], :sound_buffer_t
|
|
85
|
+
attach_function :sfSoundBufferRecorder_setDevice, [:sound_buffer_recorder_t, :string], :bool
|
|
86
|
+
attach_function :sfSoundBufferRecorder_getDevice, [:sound_buffer_recorder_t], :string
|
|
87
|
+
attach_function :sfSoundBufferRecorder_setChannelCount, [:sound_buffer_recorder_t, :uint32], :void
|
|
88
|
+
attach_function :sfSoundBufferRecorder_getChannelCount, [:sound_buffer_recorder_t], :uint32
|
|
89
|
+
|
|
90
|
+
# SoundRecorder static helpers — query mic availability and devices.
|
|
91
|
+
attach_function :sfSoundRecorder_isAvailable, [], :bool
|
|
92
|
+
attach_function :sfSoundRecorder_getDefaultDevice, [], :string
|
|
93
|
+
attach_function :sfSoundRecorder_getAvailableDevices, [:pointer], :pointer
|
|
94
|
+
|
|
95
|
+
# ---- Listener (the "ear" — global, no handle) ----
|
|
96
|
+
attach_function :sfListener_setGlobalVolume, [:float], :void
|
|
97
|
+
attach_function :sfListener_getGlobalVolume, [], :float
|
|
98
|
+
attach_function :sfListener_setPosition, [System::Vector3f.by_value], :void
|
|
99
|
+
attach_function :sfListener_getPosition, [], System::Vector3f.by_value
|
|
100
|
+
attach_function :sfListener_setDirection, [System::Vector3f.by_value], :void
|
|
101
|
+
attach_function :sfListener_getDirection, [], System::Vector3f.by_value
|
|
102
|
+
attach_function :sfListener_setUpVector, [System::Vector3f.by_value], :void
|
|
103
|
+
attach_function :sfListener_getUpVector, [], System::Vector3f.by_value
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|