class SF::Music

Overview

Streamed music played from an audio file

Musics are sounds that are streamed rather than completely loaded in memory. This is especially useful for compressed musics that usually take hundreds of MB when they are uncompressed: by streaming it instead of loading it entirely, you avoid saturating the memory and have almost no loading delay. This implies that the underlying resource (file, stream or memory buffer) must remain valid for the lifetime of the SF::Music object.

Apart from that, a SF::Music has almost the same features as the SF::SoundBuffer / SF::Sound pair: you can play/pause/stop it, request its parameters (channels, sample rate), change the way it is played (pitch, volume, 3D position, ...), etc.

As a sound stream, a music is played in its own thread in order not to block the rest of the program. This means that you can leave the music alone after calling play(), it will manage itself very well.

Usage example:

# Declare a new music
music = SF::Music.new

# Open it from an audio file
if !music.open_from_file("music.ogg")
  # error...
end

# Change some parameters
music.set_position(0, 1, 10) # change its 3D position
music.pitch = 2              # increase the pitch
music.volume = 50            # reduce the volume
music.loop = true            # make it loop

# Play it
music.play

See also: SF::Sound, SF::SoundStream

Defined in:

audio/audio.cr
audio/obj.cr

Constructors

Instance Method Summary

Instance methods inherited from class SF::SoundStream

channel_count : Int32 channel_count, finalize finalize, loop : Bool loop, loop=(loop : Bool) loop=, on_get_data : Slice(Int16) | Nil on_get_data, on_loop : Int64 on_loop, on_seek(time_offset : Time) on_seek, pause pause, play play, playing_offset : Time playing_offset, playing_offset=(time_offset : Time) playing_offset=, sample_rate : Int32 sample_rate, status : SoundSource::Status status, stop stop

Constructor methods inherited from class SF::SoundStream

new(channel_count : Int, sample_rate : Int) new

Instance methods inherited from class SF::SoundSource

attenuation : Float32 attenuation, attenuation=(attenuation : Number) attenuation=, finalize finalize, min_distance : Float32 min_distance, min_distance=(distance : Number) min_distance=, pause pause, pitch : Float32 pitch, pitch=(pitch : Number) pitch=, play play, position : Vector3f position, position=(position : Vector3f) position=, relative_to_listener=(relative : Bool) relative_to_listener=, relative_to_listener? : Bool relative_to_listener?, set_position(x : Number, y : Number, z : Number) set_position, status : SoundSource::Status status, stop stop, volume : Float32 volume, volume=(volume : Number) volume=

Constructor Detail

def self.from_file(*args, **kwargs) : self #

Shorthand for music = Music.new; music.open_from_file(...); music

Raises InitError on failure


[View source]
def self.from_memory(*args, **kwargs) : self #

Shorthand for music = Music.new; music.open_from_memory(...); music

Raises InitError on failure


[View source]
def self.from_stream(*args, **kwargs) : self #

Shorthand for music = Music.new; music.open_from_stream(...); music

Raises InitError on failure


[View source]
def self.new #

Default constructor


[View source]

Instance Method Detail

def duration : Time #

Get the total duration of the music

Returns: Music duration


[View source]
def finalize #

Destructor


[View source]
def loop_points : Music::TimeSpan #

Get the positions of the of the sound's looping sequence

Returns: Loop Time position class.

WARNING Since #loop_points=() performs some adjustments on the provided values and rounds them to internal samples, a call to #loop_points() is not guaranteed to return the same times passed into a previous call to #loop_points=(). However, it is guaranteed to return times that will map to the valid internal samples of this Music if they are later passed to #loop_points=().

See also: #loop_points=


[View source]
def loop_points=(time_points : Music::TimeSpan) #

Sets the beginning and end of the sound's looping sequence using SF::Time

Loop points allow one to specify a pair of positions such that, when the music is enabled for looping, it will seamlessly seek to the beginning whenever it encounters the end. Valid ranges for time_points.offset and time_points.length are [0, Dur) and (0, Dur-offset] respectively, where Dur is the value returned by #duration(). Note that the EOF "loop point" from the end to the beginning of the stream is still honored, in case the caller seeks to a point after the end of the loop range. This function can be safely called at any point after a stream is opened, and will be applied to a playing sound without affecting the current playing offset.

WARNING Setting the loop points while the stream's status is Paused will set its status to Stopped. The playing offset will be unaffected.

  • time_points - The definition of the loop. Can be any time points within the sound's length

See also: #loop_points


[View source]
def on_get_data : Slice(Int16) | Nil #

Request a new chunk of audio samples from the stream source

This function fills the chunk from the next samples to read from the audio file.

  • data - Chunk of data to fill

Returns: True to continue playback, false to stop


[View source]
def on_loop : Int64 #

Change the current playing position in the stream source to the loop offset

This is called by the underlying SoundStream whenever it needs us to reset the seek position for a loop. We then determine whether we are looping on a loop point or the end-of-file, perform the seek, and return the new position.

Returns: The seek position after looping (or -1 if there's no loop)


[View source]
def on_seek(time_offset : Time) #

Change the current playing position in the stream source

  • time_offset - New playing position, from the beginning of the music

[View source]
def open_from_file(filename : String) : Bool #

Open a music from an audio file

This function doesn't start playing the music (call play() to do so). See the documentation of SF::InputSoundFile for the list of supported formats.

WARNING Since the music is not loaded at once but rather streamed continuously, the file must remain accessible until the SF::Music object loads a new music or is destroyed.

  • filename - Path of the music file to open

Returns: True if loading succeeded, false if it failed

See also: #open_from_memory, #open_from_stream


[View source]
def open_from_memory(data : Slice) : Bool #

Open a music from an audio file in memory

This function doesn't start playing the music (call play() to do so). See the documentation of SF::InputSoundFile for the list of supported formats.

WARNING Since the music is not loaded at once but rather streamed continuously, the data buffer must remain accessible until the SF::Music object loads a new music or is destroyed. That is, you can't deallocate the buffer right after calling this function.

  • data - Slice containing the file data in memory

Returns: True if loading succeeded, false if it failed

See also: #open_from_file, #open_from_stream


[View source]
def open_from_stream(stream : InputStream) : Bool #

Open a music from an audio file in a custom stream

This function doesn't start playing the music (call play() to do so). See the documentation of SF::InputSoundFile for the list of supported formats.

WARNING Since the music is not loaded at once but rather streamed continuously, the stream must remain accessible until the SF::Music object loads a new music or is destroyed.

  • stream - Source stream to read from

Returns: True if loading succeeded, false if it failed

See also: #open_from_file, #open_from_memory


[View source]