palace/html/_sources/tutorial/play-audio.rst.txt

102 lines
3.1 KiB
ReStructuredText

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.