Play an Audio

Now that you know how to create a context, let’s get into the most essential use case: playing audio.

Creating a Source

To play an audio, you have to create a source. This source is an imaginary sound broadcaster, whose positions and properties can be changed to create desired effects.

from palace import Device, Context, Source

with Device() as dev, Context(dev) as ctx:
    with Source() as src:
        # to be written

Just like for the case of Context, Source creation requires a context, but here the context is passed implicitly.

Decode the Audio File

Palace has a module level function decode(), which decodes audio file automatically, and this decoded file is a Decoder object. This object can be played by a simple Decoder.play() method.

from palace import Device, Context, Source, decode

filename = 'some_audio.ogg'
with Device() as dev, Context(dev) as ctx:
    with Source() as src:
        dec = decode(filename)

We are almost there. Now, let’s look at the document for Decoder.play(). The method takes 3 parameters: chunk_len, queue_size, and source.

The source object is optional, because if you don’t have it, a new source will be generated by default.

The audio is divided into chunks, each of which is of length chunk_len. Then queue_size is the number of these chunks that it will play.

from palace import Device, Context, Source, decode

filename = 'some_audio.ogg'
with Device() as dev, Context(dev) as ctx:
    with Source() as src:
        dec = decode(filename)
        dec.play(12000, 4, src)

But we don’t want it to play only a small part of the audio. We want it to play all of it. How do we do that? The answer is a loop.

There is a method, Context.update(), which update the context and the source. When the source is updated, it will be filled with new chunks of data from the decoder.

from palace import Device, Context, Source, decode

filename = 'some_audio.ogg'
with Device() as dev, Context(dev) as ctx:
    with Source() as src:
        dec = decode(filename)
        dec.play(12000, 4, src)
        while src.playing:
            ctx.update()

If you tried this code for a song, you will find that it’s a bit rush. That is because the source is renewed too fast. So, a simple solution is to sleep for a while.

from time import sleep
from palace import Device, Context, Source, decode

filename = 'some_audio.ogg'
with Device() as dev, Context(dev) as ctx:
    with Source() as src:
        dec = decode(filename)
        dec.play(12000, 4, src)
        while src.playing:
            sleep(0.025)
            ctx.update()

Congratulation! Enjoy your music before we get to the next part of this tutorial.