Class: SFML::SoundBuffer

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

Overview

Decoded audio data held in memory. Use it to back one or more Sound instances. Loaded from .wav, .ogg, .flac, .mp3 (depends on CSFML build).

buffer = SFML::SoundBuffer.load("assets/blip.wav")
sound  = SFML::Sound.new(buffer)
sound.play

Constant Summary collapse

DEFAULT_CHANNEL_MAPS =

Default channel-layout map for the common 1- and 2-channel cases — saves callers from spelling out the SoundChannel enum just to build a mono blip or stereo waveform.

{
  1 => [1],          # sfSoundChannelMono
  2 => [2, 3],       # sfSoundChannelFrontLeft, FrontRight
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#handleObject (readonly)

:nodoc:



104
105
106
# File 'lib/sfml/audio/sound_buffer.rb', line 104

def handle
  @handle
end

Class Method Details

.from_memory(bytes) ⇒ Object

Decode a Ruby String of bytes (.wav, .ogg, .flac, …) straight into a buffer — bypass the disk.

Raises:

  • (ArgumentError)


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

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

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

  buf = allocate
  buf.send(:_take_ownership, ptr)
  buf
end

.from_samples(samples, sample_rate:, channel_count:, channel_map: nil) ⇒ Object

Build a buffer from raw 16-bit signed samples. ‘samples` is an Array of Integers in [-32768, 32767]. The caller specifies `sample_rate` (Hz) and `channel_count` (1 = mono, 2 = stereo). `channel_map` is an Array of `sfSoundChannel` enum values; for 1- and 2-channel content the default mono / front-L+R layout is filled in automatically.

Raises:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/sfml/audio/sound_buffer.rb', line 46

def self.from_samples(samples, sample_rate:, channel_count:, channel_map: nil)
  arr = samples.to_a.map { |s| Integer(s) }
  buf = FFI::MemoryPointer.new(:int16, arr.length)
  buf.write_array_of_int16(arr)

  map = channel_map || DEFAULT_CHANNEL_MAPS.fetch(channel_count) do
    raise ArgumentError,
          "no default channel_map for #{channel_count} channels — pass `channel_map: [...]` explicitly"
  end
  map_buf = FFI::MemoryPointer.new(:int, map.length)
  map_buf.write_array_of_int(map.map { |v| Integer(v) })

  ptr = C::Audio.sfSoundBuffer_createFromSamples(buf, arr.length,
                                                 Integer(channel_count),
                                                 Integer(sample_rate),
                                                 map_buf, map.length)
  raise Error, "sfSoundBuffer_createFromSamples returned NULL" if ptr.null?

  sb = allocate
  sb.send(:_take_ownership, ptr)
  sb
end

.load(path) ⇒ Object

Raises:



9
10
11
12
13
14
15
# File 'lib/sfml/audio/sound_buffer.rb', line 9

def self.load(path)
  ptr = C::Audio.sfSoundBuffer_createFromFile(path.to_s)
  raise Error, "Could not load sound buffer from #{path.inspect}" if ptr.null?
  buf = allocate
  buf.send(:_take_ownership, ptr)
  buf
end

Instance Method Details

#channel_countObject



71
# File 'lib/sfml/audio/sound_buffer.rb', line 71

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

#dupObject Also known as: clone

Independent copy — same decoded waveform, different underlying memory block.

Raises:



85
86
87
88
89
90
91
92
# File 'lib/sfml/audio/sound_buffer.rb', line 85

def dup
  ptr = C::Audio.sfSoundBuffer_copy(@handle)
  raise Error, "sfSoundBuffer_copy returned NULL" if ptr.null?

  copy = self.class.allocate
  copy.send(:_take_ownership, ptr)
  copy
end

#durationObject



69
# File 'lib/sfml/audio/sound_buffer.rb', line 69

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

#sample_countObject



72
# File 'lib/sfml/audio/sound_buffer.rb', line 72

def sample_count  = C::Audio.sfSoundBuffer_getSampleCount(@handle)

#sample_rateObject



70
# File 'lib/sfml/audio/sound_buffer.rb', line 70

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

#samplesObject

The decoded 16-bit signed samples as a Ruby Array of Integers. Heavy — copies every sample. For analysis or custom DSP that needs the raw waveform.



77
78
79
80
81
# File 'lib/sfml/audio/sound_buffer.rb', line 77

def samples
  ptr = C::Audio.sfSoundBuffer_getSamples(@handle)
  return [] if ptr.null?
  ptr.read_array_of_int16(sample_count)
end

#save(path) ⇒ Object

Write the buffer out to disk. Format is inferred from the file extension (.wav / .ogg / .flac, depends on what CSFML was built with).

Raises:



98
99
100
101
102
# File 'lib/sfml/audio/sound_buffer.rb', line 98

def save(path)
  ok = C::Audio.sfSoundBuffer_saveToFile(@handle, path.to_s)
  raise Error, "could not save SoundBuffer to #{path.inspect}" unless ok
  path
end