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

#handle ⇒ Object (readonly)

:nodoc:



122
123
124
# File 'lib/sfml/audio/sound_buffer.rb', line 122

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)


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

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 LoadError, "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:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sfml/audio/sound_buffer.rb', line 60

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 AudioError, "sfSoundBuffer_createFromSamples returned NULL" if ptr.null?

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

.from_stream(io) ⇒ Object

Load fully-decoded audio from any Ruby IO-like object. The whole stream is decoded into RAM — for streaming playback, use Music.from_stream instead.

Raises:



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

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

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

.load(path) ⇒ Object

Returns the self.

Raises:



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

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

Instance Method Details

#channel_count ⇒ Object

Returns the channel count.



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

def channel_count = C::Audio.sfSoundBuffer_getChannelCount(@handle)
# Returns the sample count.

#dup ⇒ Object Also known as: clone

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

Raises:



103
104
105
106
107
108
109
110
# File 'lib/sfml/audio/sound_buffer.rb', line 103

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

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

#duration ⇒ Object

Returns the duration.



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

def duration      = Time.from_native(C::Audio.sfSoundBuffer_getDuration(@handle))
# Returns the sample rate.

#sample_count ⇒ Object

Returns the sample count.



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

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

#sample_rate ⇒ Object

Returns the sample rate.



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

def sample_rate   = C::Audio.sfSoundBuffer_getSampleRate(@handle)
# Returns the channel count.

#samples ⇒ Object

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.



95
96
97
98
99
# File 'lib/sfml/audio/sound_buffer.rb', line 95

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:



116
117
118
119
120
# File 'lib/sfml/audio/sound_buffer.rb', line 116

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