:mod:`pygame2.openal` -- basic OpenAL wrapper module
====================================================

.. todo::

       detailled description of the OpenAL model, including contexts, devices,
       source and listener bindings and the context/state driven behaviour.

Type identifiers for the property get and set methods:

+------+------------------------------------------------------------+
| 'b'  | Get or set a single boolean value (e.g. AL_TRUE)           |
+------+------------------------------------------------------------+
| 'ba' | Get or set an array of boolean values. The array can be    |
|      | any type of sequence containing matching values.           |
+------+------------------------------------------------------------+
| 'i'  | Get or set a single integer value.                         |
+------+------------------------------------------------------------+
| 'i3' | Get or set an triplet of integer values. The array can be  |
|      | any type of sequence containing matching values.           |
+------+------------------------------------------------------------+
| 'ia' | Get or set an array of integer values. The array can be    |
|      | any type of sequence containing matching values.           |
+------+------------------------------------------------------------+
| 'f'  | Get or set a single floating point value.                  |
+------+------------------------------------------------------------+
| 'f3' | Get or set an triplet of floating point values. The array  |
|      | can be any type of sequence containing matching values.    |
+------+------------------------------------------------------------+
| 'fa' | Get or set an array of floating point values. The array    |
|      | can be any type of sequence containing matching values.    |
+------+------------------------------------------------------------+
| 'd'  | Get or set a single double precision floating point value. |
+------+------------------------------------------------------------+
| 'da' | Get or set an array of double precision floating point     |
|      | values. The array can be any type of sequence containing   |
|      | matching values.                                           |
+------+------------------------------------------------------------+


.. module:: pygame2.openal
   :synopsis: basic OpenAL wrapper module

Module Functions
----------------
.. function:: al_get_string (prop) -> str

  Retrieves an OpenAL string property.

  For valid property values, see :mod:`pygame2.openal.constants`.



  **Example:** ::
    
    import pygame2.openal as openal
    import pygame2.openal.constants as const
    
    print (openal.al_get_string (const.AL_VENDOR))
    

.. function:: get_default_capture_device_name () -> str

  Gets the name of the default capture device.


.. function:: get_default_output_device_name () -> str

  Gets the name of the default output device.


.. function:: get_enum_value (name) -> long

  Gets the value of an OpenAL enumeration name.


.. function:: get_error () -> str

  Gets the last OpenAL error message occured.

  OpenAL maintains an internal error message. This message will usually
  be given to you when a :exc:`pygame2.Error` is raised.

  You will rarely need to call this function.

  .. note::

          Once called, the internal OpenAL error message will be cleared, so that
          subsequent calls of this function will return *None*, until a new
          OpenAL error occurs.



.. function:: init ()

  Initializes the underlying OpenAL library.

  .. note::

          This function is currently only available for compliance with other
          pygame2 modules, but does not actually perform anything. The behaviour
          might change in later pygame2 versions, so it is generally safe to call
          this function.



.. function:: is_extension_present (name[, device]) -> bool

  Checks, whether the specified extension is available.

  Checks, whether the extension specified by *name* is available in the
  current OpenAL implementation. If a *device* is passed, the OpenAL's
  :pygame2.openal.Device` will be checked for the extension.



.. function:: list_capture_devices () -> [str, str, ...]

  Retrieves a list of available capture devices.

  Retrieves a list of available and supported capture device names. If no
  capture devices could be found, an empty list is returned.



.. function:: list_output_devices

  Retrieves a list of available output devices.

  Retrieves a list of available and supported output device names. If no
  output devices could be found, an empty list is returned.



.. function:: quit ()

  Shuts down the underlying OpenAL library.

  .. note::

          This function is currently only available for compliance with other
          pygame2 modules, but does not actually perform anything. The behaviour
          might change in later pygame2 versions, so it is generally safe to call
          this function.



.. function:: set_current_context (context) -> bool

  Switches the current OpenAL context.

  Switches the current OpenAL context. The current OpenAL context can then
  be influenced in various ways, such as attaching sources, buffers and
  tweaking its settings.

  Returns True, if the context could be switched successfully, otherwise
  False.



Buffers
-------
.. class:: Buffers () -> NotImplementedError

  Buffers objects are used by OpenAL to buffer and provide PCM data
  for playback, recording and manipulation.

  The Buffers object provides methods and properties to manipulate
  certain aspects of the buffered data and can be queued to multiple
  Sources within the same context.

  Buffers instances cannot be created directly, but are bound to a
  :class:`Device`. To create a Buffers instance for the currently
  active :class:`Device`, use the :meth:`Context.create_buffers` method
  on the currently active :class:`Context`.


Attributes
^^^^^^^^^^
.. attribute:: Buffers.buffers

  Gets the buffer identifiers used in the Buffers instance.

.. attribute:: Buffers.count

  Gets the number of buffers managed in the Buffers instance.

Methods
^^^^^^^
.. method:: Buffers.buffer_data (bufnum, format, data, samplerate) -> None

  Buffers a chunk of *data* into one of the created buffers.

  Buffers a chunk of PCM *data* into the buffer at *bufnum*. *format*
  describes the audio format of the data (see
  :mod:`pygame2.openal.constants` for
  more details). *samplerate* denotes the sample rate in Hz.


.. method:: Buffers.get_prop (bufnum, prop, type) -> value or (value, ...)

  Retrieves the value(s) of an OpenAL property for the Buffers.

  Retrieves the value or values of a buffer-related OpenAL property for
  the buffer identified by *bufnum*. *prop* can be any valid buffer
  constant and *type* **must** be a valid value type identifier for the
  constant.


.. method:: Buffers.set_prop (bufnum, prop, value[,type]) -> None

  Sets the value(s) of an OpenAL property for the Buffers.

  Sets the value or values of a buffer-related OpenAL property for the
  buffer identified by *bufnum*. *prop* can be any valid buffer
  constant, while *value* **must** be valid for the constant.

  If *type* is omitted, the function tries to guess, which type should be
  used from the passed value(s). Guessing tries to convert values
  implicitly, where possible, so if there are ambiguous values, it is
  better to provide *type*.


CaptureDevice
-------------
.. class:: CaptureDevice (frequency, format, bufsize) -> CaptureDevice
    CaptureDevice (name, frequency, format, bufsize) -> CaptureDevice
    

  Creates a sound capturing device.

  The CaptureDevice acts as recorder for a certain hardware device and
  allows the caller to record incoming sound samples (e.g. from a
  microphone or line-in device).

  The captured samples will be stored in an internal buffer, which is
  guaranteed to hold *bufsize* samples. Depending on the passed
  *format* and *frequency*, captured samples can vary in their byte
  size (see :mod:`pygame2.openal.constants` for more details) and
  speed of occurance.


Attributes
^^^^^^^^^^
.. attribute:: CaptureDevice.format

  Gets the set audio format for the CaptureDevice.

.. attribute:: CaptureDevice.frequency

  Gets the set frequency in Hz for the CaptureDevice.

.. attribute:: CaptureDevice.size

  Gets the default buffer size for the CaptureDevice.

Methods
^^^^^^^
.. method:: CaptureDevice.get_samples ([buffer]) -> (str or bytes) or int

  Retrieves the available samples from the CaptureDevice.

  Retrieves the samples that are available on the CaptureDevice. If
  a *buffer* is provided, the samples will be directly written to
  the buffer and the amount of bytes written will be returned.

  If no *buffer* is provided, the retrieved samples will be returned
  as byte sequence (byte string or string).


.. method:: CaptureDevice.start () ->None

  Starts capturing incoming samples on the device.

  Starts capturing incoming samples for the CaptureDevice. The
  samples will be stored in the CaptureDevice's internal buffer. If
  the buffer is full, the oldest samples will be overwritten with
  the newest samples (ring buffer).


.. method:: CaptureDevice.stop () -> None

  Stops capturing incoming samples.

Context
-------
.. class:: Context (device[,attribtes]) -> Context

  Creates a new Context for a specific Device.

  OpenAL contexts represent logical state groups, where
  :class:`Sources` and a :class:`Listener` are managed and audio
  data is correctly streamed to the underlying output
  :class:`Device`.

  Contexts can be created for multiple devices and independently
  managed without influencing each other. To be processed correctly
  at a certain time, a :class:`Context` must be set as the *current*
  one in OpenAL. This will cause OpenAL to process only data from
  that :class:`Context` to and from the audio hardware.

  Most methods and properties will fail for a :class:`Context` that
  is not marked as the *current* one. So before accessing any member
  of a :class:`Context`, make sure, you marked it as *current*.


Attributes
^^^^^^^^^^
.. attribute:: Context.device

  Gets the :class:`Device` the Context is using.

.. attribute:: Context.distance_model

  Gets or sets the distance model setting for the
  :class:`Context`.

.. attribute:: Context.doppler_factor

  Gets or sets the doppler factor setting for the
  :class:`Context`.

.. attribute:: Context.is_current

  Gets, whether the :class:`Context` is marked the current one
  to process.

.. attribute:: Context.listener

  Gets the :class:`Listener` for the :class:`Context`.

.. attribute:: Context.speed_of_sound

  Gets or sets the value of the speed of sound for the
  :class:`Context`.

Methods
^^^^^^^
.. method:: Context.create_buffers (amount) -> Buffers

  Creates a Buffers instance with *amount* buffers for the Context.


.. method:: Context.create_sources (amount) -> Sources

  Creates a Sources instance with *amount* sources for the Context.


.. method:: Context.disable (value) -> None

  Disables a certain context-specific setting.

.. method:: Context.enable (value) -> None

  Enables a certain context-specific setting.

.. method:: Context.is_enabled (value) -> bool

  Checks, whether a certain setting is enabled.

.. method:: Context.make_current () -> bool

  Tries to mark the :class:`Context` as current.

  Tries to mark the :class:`Context` as the current one. If the
  :class:`Context` could not be marked sucessfully, False will be
  returned, otherwise True.

  Any other :class:`Context`, which was previously marked as
  current, will loose this state.


.. method:: Context.process () -> None

  Processes the :class:`Context`.

  Processes the :class:`Context`, causing it to update any
  internal states, stream audio data to and from the hardware,
  update the internal source and listener positions and so forth.


.. method:: Context.suspend () -> None

  Suspends the :class:`Context` from processing any data.

Device
------
.. class:: Device ([name]) -> Device

  Creates a sound output device.

  The Device class acts as sound streaming sink, by default for
  playing audio data (The :class:`CaptureDevice` also inherits from
  :class:`Device`, but acts as recorder).


Attributes
^^^^^^^^^^
.. attribute:: Device.extensions

  Gets a list of available extensions for the Device and
  OpenAL implementation.


.. attribute:: Device.name

  Gets the name of the Device as reported by OpenAL.

Methods
^^^^^^^
.. method:: Device.get_enum_value (name) -> long

  Gets the value of a Device-specific OpenAL enumeration name.


.. method:: Device.get_error () -> str

  Gets the last OpenAL error message occured on the Device.

  OpenAL devices maintain an internal error message. This message
  will usually be given to you when a :exc:`pygame2.Error` is
  raised.

  You will rarely need to call this function.

  .. note::

            Once called, the internal error message will be cleared, so
            that subsequent calls of this function will return *None*,
            until a new error occurs.


.. method:: Device.has_extension (extname) -> bool

  Checks, whether a certain extension is available on the Device.


Listener
--------
.. class:: Listener () -> NotImplementedError

  The Listener represents the user hearing the sounds played by OpenAL in a
  specific Context. Source playback is done relative to the position of the
  Listener in the 3D space.

  Listener instances cannot be created directly, but are bound to a
  :class:`Context`. To create (or get) a Listener instance for the
  currently active :class:`Context`, use the :attr:`Context.listener`
  property.


Methods
^^^^^^^
.. method:: Listener.get_prop (prop, type) -> value or (value, ...)

  Retrieves the value(s) of an OpenAL property for the Listener.

  Retrieves the value or values of a listener-related OpenAL property.
  *prop* can be any valid listener constant and *type* **must** be a
  valid value type identifier for the constant.


.. method:: Listener.set_prop (prop, value[, type]) -> None

  Sets the value(s) of an OpenAL property for the Listener.

  Sets the value or values of a listener-related OpenAL property.
  *prop* can be any valid listener constant, while *value* **must** be
  valid for the constant.

  If *type* is omitted, the function tries to guess, which type should be
  used from the passed value(s). Guessing tries to convert values
  implicitly, where possible, so if there are ambiguous values, it is
  better to provide *type*.


Sources
-------
.. class:: Sources () -> NotImplementedError

  Sources store locations, directions, and other attributes of an object in
  3D space and have a buffer associated with them for playback. When the
  program wants to play a sound, it controls execution through a source
  object. Sources are processed independently from each other.

  Sources instances cannot be created directly, but are bound to a
  :class:`Context`. To create a Sources instance for the currently
  active :class:`Context`, use the :meth:`Context.create_sources` method.


Attributes
^^^^^^^^^^
.. attribute:: Sources.count

  Gets the number of sources managed in the Sources instance.

.. attribute:: Sources.sources

  Gets the source identifiers used in the Sources instance.

Methods
^^^^^^^
.. method:: Sources.get_prop (sourcenum, prop, type) -> value or (value, ...)

  Retrieves the value(s) of an OpenAL property for the Sources.

  Retrieves the value or values of a sources-related OpenAL property for
  the source identified by *sourcenum*. *prop* can be any valid source
  constant and *type* **must** be a valid value type identifier for the
  constant.


.. method:: Sources.pause (sourcenum) -> None
            Sources.pause ((sourcenum1, sourcenum2, ...)) -> None

  Pauses a single source or a set of sources.

  Pauses a single source identified by *sourcenum* or a set of sources
  identified by the passed sequence of source identifiers.


.. method:: Sources.play (sourcenum) -> None
            Sources.play ((sourcenum1, sourcenum2, ...)) -> None

  Plays a single source or a set of sources.

  Plays a single source identified by *sourcenum* or a set of sources
  identified by the passed sequence of source identifiers.


.. method:: Sources.queue_buffers (sourcenum, buffers) -> None

  Queues a :class:`Buffers` on a source.

  Queues a :class:`Buffers` instance holding one or multiple audio buffers
  on the source identified by *sourcenum*. The audio buffers in *buffers*
  will be played in sequence.

  To retrieve the number of audio buffers already processed, you can query
  the source with the :const:`AL_BUFFERS_PROCESSED` constant.


.. method:: Sources.rewind (sourcenum) -> None
            Sources.rewind ((sourcenum1, sourcenum2, ...)) -> None

  Rewinds a single source or a set of sources.

  Rewinds a single source identified by *sourcenum* or a set of sources
  identified by the passed sequence of source identifiers.


.. method:: Sources.set_prop (sourcenum, prop, value[, type]) -> None

  Sets the value(s) of an OpenAL property for the Sources.

  Sets the value or values of a sources-related OpenAL property for the
  source identified by *sourcenum*. *prop* can be any valid source
  constant, while *value* **must** be valid for the constant.

  If *type* is omitted, the function tries to guess, which type should be
  used from the passed value(s). Guessing tries to convert values
  implicitly, where possible, so if there are ambiguous values, it is
  better to provide *type*.


.. method:: Sources.stop (sourcenum) -> None
            Sources.stop ((sourcenum1, sourcenum2, ...)) -> None

  Stops playing a single source or a set of sources.

  Stops playing a single source identified by *sourcenum* or a set of
  sources identified by the passed sequence of source identifiers.


.. method:: Sources.unqueue_buffers (sourcenum, buffers) -> None

  Unqueues processed :class:`Buffers` from a source

  Unqueus an already processed :class:`Buffers` with one or multiple audio
  buffers from the source identified by *sourcenum*.

  .. note::

            This will only succeed, when all buffers within the :class:`Buffers`
            instance were processed by the source. Otherwise a
            :exc:`pygame2.Error` will be raised.



