Play an Audio ============= .. currentmodule:: palace 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. .. code-block:: python 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 :py:class:`Context`, :py:class:`Source` creation requires a context, but here the context is passed implicitly. Decode the Audio File --------------------- Palace has a module level function :py:func:`decode`, which decodes audio file automatically, and this decoded file is a :py:class:`Decoder` object. This object can be played by a simple :py:meth:`Decoder.play` method. .. code-block:: python 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 :py:meth:`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. .. TODO: I think it's better to include a diagram here. Add later .. code-block:: python 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, :py:meth:`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. .. code-block:: python 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. .. code-block:: python 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.