Sound Library
    The sound library is an external library for managing audio. It provides an interface for working
    with streams of sound data that is similar to the IO part of the
    standard library (but works on 32-bit floating point values instead of bytes). It also provides
    decoding of common audio formats (currently, mp3, ogg, flac, and wav), and playback of audio
    streams. The library also defines a thread, sound.Audio, for executing sound-related
    code.
The remainder of this part of the manual provides an overview of these interfaces.
Sound
    The type sound.Sound represents a stream of audio samples. As such, it is analogous to
    the type core.io.IStream in the standard library. The type itself does not provide any
    audio data. Any of the derived types may be used for this purpose.
    A sound stream is considered to consist of a sequence of samples. Each sample is represented by a
    32-bit floating point number (core.Float). If the sound stream contains multiple
    channels, samples for all channels are interleaved in the stream as specified by the vorbis
    format. For example, for 2 channels, the first sample is for the left channel, the second is for the
    right, and so on. The interface expects consumers of the sound data to work in multiples of the
    channel size.
Audio streams may be seekable or non-seekable. Seekable streams return a non-zero length, while non-seekable streams return a zero length.
The type has the following members:
- 
        core.Nat sampleFreq()Get the sample frequency of the stream, measured in samples per second. 
- 
        core.Nat channels()Get the number of channels for this stream. 
- 
        void close()Close the stream now. Also closes any underlying input streams for this stream. 
- 
        core.Bool more()Is more data available in the stream? Might return false only after reading zero bytes for the first time. 
- 
        core.Word length()Get the length of the stream, measured in samples. Returns zero if the stream is not seekable. 
- 
        core.Bool seek(core.Word to)Seek in the input stream. Returns falseif seeking is not supported, or an error occurred. The position is measured in samples. The position is expected to be a multiple of the number of channels.
- 
        core.Word tell()Get the current position, measured in samples. May return zero for non-seekable streams. 
- 
        sound.Buffer read(sound.Buffer to)Attempt to fill the buffer towith samples from the stream. Fills the bytes fromfilledtocountin the buffer. Only reads a multiple ofchannelssamples from the stream. If zero samples are read, then the end of the stream is reached.
- 
        sound.Buffer read(core.Nat samples)Read data from the buffer into a new, empty buffer with space for the specified number of samples. 
Reading Sound
As mentioned above, the library contains support for some common audio formats, namely mp3, ogg, flac, and wav. Support for most of these are provided by external libraries that are compiled into the library on most platforms. Support for wav is native to the library, and as such support for compressed wav-files is limited.
The library provides the following classes to decode the different formats:
- 
        sound.Mp3Sound
- 
        sound.OggSound
- 
        sound.FlacSound
- 
        sound.WavSound
    These are generally created by the functions openX or openXStream. The former accepts a
    core.io.RIStream and creates a seekable stream, while the latter accepts a
    core.io.IStream and creates a non-seekable stream.
The library also provides generic operations for opening sound files and automatically deducing the file format based on the header in the file:
- 
        sound.Sound sound(core.io.IStream src)Create a sound stream for reading srcbased on the header insrc. Will makesrcinto a seekable stream to provide a seekable audio stream.
- 
        sound.Sound soundStream(core.io.IStream src)Open sound from a streaming source. The resulting stream will not be seekable. 
- 
        sound.Sound readSound(core.io.Url file)Calls sound(file.read()).
- 
        sound.Sound readSoundStream(core.io.Url file)Calls soundStream(file.read()).
Buffer
    The sound.Buffer represents a series of samples, represented as 32-bit floating point
    values in the range 1.0 to -1.0. The interface closely resembles that of core.io.Buffer,
    which is documented here.
    As with the buffers in the IO library, copies of buffers generally refer to the same data, but are
    copied across thread boundaries. As such, when using the read function in a Sound stream, it is
    important to use the returned buffer, even though the buffer that was passed to the function is
    updated in most cases.
    The Buffer has the following members:
- 
        init()Default constructor. Create an empty buffer. Use the function bufferto create a buffer with non-zero size.
- 
        core.Nat count()Get the number of samples in the buffer in total. 
- 
        core.Nat filled()Get the number of samples from the beginning of the buffer that are considered to contain valid data. The buffer itself generally does not use this value. Rather, it is used as an universal marker for how much of the buffer is used for actual data, and how much is free. 
- 
        void filled(core.Nat p)Set the number of samples that are used. Limits the value to be maximum count. Marked as an assign functions, so thatfilledcan be used as a member variable in languages like Basic Storm.
- 
        core.Nat free()Get the number of free samples in the buffer, based on the filledmember.
- 
        core.Float& [](core.Nat id)Access individual samples. 
- 
        core.Bool empty()Is the buffer empty according to the filledmember?
- 
        core.Bool full()Is the buffer full, according to the filledmember?
- 
        void toS(core.StrBuf to)Output. A toS() is generated automatically. 
- 
        void outputMark(core.StrBuf to, core.Nat markAt)Output the buffer, specifying an additional mark. 
    The buffer also has the following free function buffer to create buffers:
- 
        sound.Buffer buffer(core.Nat count)Create a buffer with room for countbytes. It will be empty initially.
Player
    The type sound.Player represents an audio stream that is being played on the system's
    default speakers. On Windows, it uses the DirectSound API, and on Linux it relies on OpenAL. The
    implementation typicallby buffers some amount of sound data internally to avoid artifacts. The
    Player provides basic controls for the audio playback:
- 
        init(sound.Sound sound)Create a player that plays the specified sound. ThePlayertakes responsibility for closing the sound stream eventually, and assumes that the sound stream is not modified externally. Will not play the sound untilplayis called.
- 
        void close()Destroy any resources associated with the Player. The destructor automatically callscloseeventually, but since this does not always happen promptly, it is a good idea to manually callclosewhenever possible.
- 
        void play()Start playing the sound. 
- 
        core.Bool playing()Is the stream currently playing? 
- 
        void pause()Pause the sound. 
- 
        void stop()Stop playing the sound. This also resets the playback position to zero (for seekable streams). 
- 
        core.Duration time()Get the time of playback. 
- 
        core.Float volume()Get the current volume. 
- 
        void volume(core.Float level)Set the sound volume (between 0 and 1). Marked as an assign function, so that volumecan be treated as a member variable.
- 
        void wait()Wait until playback reaches the end of the stream, or until playback is stopped. Do not call from the UThread that manages callbacks. 
- 
        void waitUntil(core.Duration t)Wait until playback reaches or passes the specific duration since start, or if the player is stopped. Do not call from the UThread managing callbacks. 
