// Generated by gmmproc 2.50.1 -- DO NOT MODIFY!
#ifndef _GSTREAMERMM_AUDIORINGBUFFER_H
#define _GSTREAMERMM_AUDIORINGBUFFER_H


#include <glibmm/ustring.h>
#include <sigc++/sigc++.h>

/* gstreamermm - a C++ wrapper for gstreamer
 *
 * Copyright 2008-2016 The gstreamermm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gst/audio/audio.h>
#include <gst/audio/gstaudioringbuffer.h>
#include <gstreamermm/caps.h>
#include <gstreamermm/object.h>
#include <gstreamermm/format.h>
#include <gstreamermm/clock.h>
#include <glibmm/arrayhandle.h>
#include <memory>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
using GstAudioRingBuffer = struct _GstAudioRingBuffer;
using GstAudioRingBufferClass = struct _GstAudioRingBufferClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Gst
{ class AudioRingBuffer_Class; } // namespace Gst
#endif //DOXYGEN_SHOULD_SKIP_THIS

namespace Gst
{

/** @addtogroup gstreamermmEnums gstreamermm Enums and Flags */

/** 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_MONO
 * Mono without direction;
 * can only be used with 1 channel.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_FRONT_LEFT
 * Front left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_FRONT_RIGHT
 * Front right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_FRONT_CENTER
 * Front center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_LFE1
 * Low-frequency effects 1 (subwoofer).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_REAR_LEFT
 * Rear left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_REAR_RIGHT
 * Rear right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
 * Front left of center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
 * Front right of center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_REAR_CENTER
 * Rear center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_LFE2
 * Low-frequency effects 2 (subwoofer).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_SIDE_LEFT
 * Side left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_SIDE_RIGHT
 * Side right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT
 * Top front left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT
 * Top front right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER
 * Top front center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_CENTER
 * Top center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT
 * Top rear left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT
 * Top rear right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT
 * Top side right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT
 * Top rear right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER
 * Top rear center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER
 * Bottom front center.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT
 * Bottom front left.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT
 * Bottom front right.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_WIDE_LEFT
 * Wide left (between front left and side left).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_WIDE_RIGHT
 * Wide right (between front right and side right).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_SURROUND_LEFT
 * Surround left (between rear left and side left).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_SURROUND_RIGHT
 * Surround right (between rear right and side right).
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_NONE
 * Used for position-less channels, e.g.
 * from a sound card that records 1024 channels; mutually exclusive with
 * any other channel position.
 * 
 *  @var AudioChannelPosition AUDIO_CHANNEL_POSITION_INVALID
 * Invalid position.
 * 
 *  @enum AudioChannelPosition
 * 
 * Audio channel positions.
 * 
 * These are the channels defined in SMPTE 2036-2-2008
 * Table 1 for 22.2 audio systems with the Surround and Wide channels from
 * DTS Coherent Acoustics (v.1.3.1) and 10.2 and 7.1 layouts. In the caps the
 * actual channel layout is expressed with a channel count and a channel mask,
 * which describes the existing channels. The positions in the bit mask correspond
 * to the enum values.
 * For negotiation it is allowed to have more bits set in the channel mask than
 * the number of channels to specify the allowed channel positions but this is
 * not allowed in negotiated caps. It is not allowed in any situation other
 * than the one mentioned below to have less bits set in the channel mask than
 * the number of channels.
 * 
 *  @a GST_AUDIO_CHANNEL_POSITION_MONO can only be used with a single mono channel that
 * has no direction information and would be mixed into all directional channels.
 * This is expressed in caps by having a single channel and no channel mask.
 * 
 *  @a GST_AUDIO_CHANNEL_POSITION_NONE can only be used if all channels have this position.
 * This is expressed in caps by having a channel mask with no bits set.
 * 
 * As another special case it is allowed to have two channels without a channel mask.
 * This implicitely means that this is a stereo stream with a front left and front right
 * channel.
 *
 * @ingroup gstreamermmEnums
 */
enum AudioChannelPosition
{
  AUDIO_CHANNEL_POSITION_NONE = -3,
  AUDIO_CHANNEL_POSITION_MONO,
  AUDIO_CHANNEL_POSITION_INVALID,
  AUDIO_CHANNEL_POSITION_FRONT_LEFT,
  AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
  AUDIO_CHANNEL_POSITION_FRONT_CENTER,
  AUDIO_CHANNEL_POSITION_LFE1,
  AUDIO_CHANNEL_POSITION_REAR_LEFT,
  AUDIO_CHANNEL_POSITION_REAR_RIGHT,
  AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
  AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
  AUDIO_CHANNEL_POSITION_REAR_CENTER,
  AUDIO_CHANNEL_POSITION_LFE2,
  AUDIO_CHANNEL_POSITION_SIDE_LEFT,
  AUDIO_CHANNEL_POSITION_SIDE_RIGHT,
  AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT,
  AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT,
  AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER,
  AUDIO_CHANNEL_POSITION_TOP_CENTER,
  AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT,
  AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT,
  AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT,
  AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT,
  AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER,
  AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER,
  AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT,
  AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT,
  AUDIO_CHANNEL_POSITION_WIDE_LEFT,
  AUDIO_CHANNEL_POSITION_WIDE_RIGHT,
  AUDIO_CHANNEL_POSITION_SURROUND_LEFT,
  AUDIO_CHANNEL_POSITION_SURROUND_RIGHT
};

} // namespace Gst

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::AudioChannelPosition> : public Glib::Value_Enum<Gst::AudioChannelPosition>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

namespace Gst
{

/** 
 *  @var AudioRingBufferState AUDIO_RING_BUFFER_STATE_STOPPED
 * The ringbuffer is stopped.
 * 
 *  @var AudioRingBufferState AUDIO_RING_BUFFER_STATE_PAUSED
 * The ringbuffer is paused.
 * 
 *  @var AudioRingBufferState AUDIO_RING_BUFFER_STATE_STARTED
 * The ringbuffer is started.
 * 
 *  @var AudioRingBufferState AUDIO_RING_BUFFER_STATE_ERROR
 * The ringbuffer has encountered an
 * error after it has been started, e.g. because the device was
 * disconnected (Since 1.2).
 * 
 *  @enum AudioRingBufferState
 * 
 * The state of the ringbuffer.
 *
 * @ingroup gstreamermmEnums
 */
enum AudioRingBufferState
{
  AUDIO_RING_BUFFER_STATE_STOPPED,
  AUDIO_RING_BUFFER_STATE_PAUSED,
  AUDIO_RING_BUFFER_STATE_STARTED,
  AUDIO_RING_BUFFER_STATE_ERROR
};

} // namespace Gst

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::AudioRingBufferState> : public Glib::Value_Enum<Gst::AudioRingBufferState>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

namespace Gst
{

/** 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_RAW
 * Samples in linear or float.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW
 * Samples in mulaw.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW
 * Samples in alaw.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_IMA_ADPCM
 * Samples in ima adpcm.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG
 * Samples in mpeg audio (but not AAC) format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_GSM
 * Samples in gsm format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_IEC958
 * Samples in IEC958 frames (e.g. AC3).
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_AC3
 * Samples in AC3 format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3
 * Samples in EAC3 format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_DTS
 * Samples in DTS format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC
 * Samples in MPEG-2 AAC format.
 * 
 *  @var AudioRingBufferFormatType AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC
 * Samples in MPEG-4 AAC format.
 * 
 *  @enum AudioRingBufferFormatType
 * 
 * The format of the samples in the ringbuffer.
 *
 * @ingroup gstreamermmEnums
 */
enum AudioRingBufferFormatType
{
  AUDIO_RING_BUFFER_FORMAT_TYPE_RAW,
  AUDIO_RING_BUFFER_FORMAT_TYPE_MU_LAW,
  AUDIO_RING_BUFFER_FORMAT_TYPE_A_LAW,
  AUDIO_RING_BUFFER_FORMAT_TYPE_IMA_ADPCM,
  AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG,
  AUDIO_RING_BUFFER_FORMAT_TYPE_GSM,
  AUDIO_RING_BUFFER_FORMAT_TYPE_IEC958,
  AUDIO_RING_BUFFER_FORMAT_TYPE_AC3,
  AUDIO_RING_BUFFER_FORMAT_TYPE_EAC3,
  AUDIO_RING_BUFFER_FORMAT_TYPE_DTS,
  AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG2_AAC,
  AUDIO_RING_BUFFER_FORMAT_TYPE_MPEG4_AAC
};

} // namespace Gst

#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Glib
{

template <>
class Value<Gst::AudioRingBufferFormatType> : public Glib::Value_Enum<Gst::AudioRingBufferFormatType>
{
public:
  static GType value_type() G_GNUC_CONST;
};

} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

namespace Gst
{


/** A class containing the format specification of a Gst::AudioRingBuffer.
 * Gst::AudioRingBufferSpec contains the format specification of a
 * Gst::AudioRingBuffer.  The "in" members should be specified by the caller of
 * the acquire() method while the "in/out" members may be
 * set by the caller but are also modifiable by
 * acquire().  The "out" members are generated as a
 * result of the call to acquire().
 * @see acquire().
 */
class AudioRingBufferSpec
{
  public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  using CppObjectType = AudioRingBufferSpec;
  using BaseObjectType = GstAudioRingBufferSpec;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

private:

public:
  /** Default constructor.
   * @throw std::runtime_error if memory is unavailable for the new
   * Gst::AudioRingBufferSpec.
   */
  AudioRingBufferSpec();

  /** Fully construct a Gst::AudioRingBufferSpec.  Only the "(in)" parameters
   * are required.  The "(in/out)" parameters are optional and may be modified
   * by the call to the Gst::AudioRingBuffer::acquire() method.
   * @param caps The caps of the buffer (in).
   * @param type The sample type (in/out).
   * @param latency_time The latency in microseconds (in/out).
   * @param buffer_time The total buffer size in microseconds (in/out).
   * @param segsize The size of one segment in bytes (in/out).
   * @param segtotal The total number of segments (in/out).
   * @param seglatency Number of segments queued in the lower level device,
   * defaults to @a segtotal in the C API (in/out).
   *
   * @throw std::runtime_error if memory is unavailable for the new
   * Gst::AudioRingBufferSpec.
   */
  AudioRingBufferSpec(const Glib::RefPtr<Gst::Caps>& caps,
    Gst::AudioRingBufferFormatType type = Gst::AUDIO_RING_BUFFER_FORMAT_TYPE_RAW,
    guint64 latency_time = 0,
    guint64 buffer_time = 0,
    int segsize = 0, int segtotal = 0, int seglatency = 0);

  /// Construct a Gst::AudioRingBufferSpec from a GstAudioRingBufferSpec.
  explicit AudioRingBufferSpec(GstAudioRingBufferSpec& castitem,
    bool take_ownership = false);

  /** Copy constructor.
   *
   * @throw std::runtime_error if memory is unavailable for the new
   * Gst::AudioRingBufferSpec.
   */
  AudioRingBufferSpec(const AudioRingBufferSpec& other);

  /// Assignment operator.
  AudioRingBufferSpec& operator=(const AudioRingBufferSpec& other);

  /// Destructor.
  virtual ~AudioRingBufferSpec();

  void swap(AudioRingBufferSpec& other);

  /// Gets the underlying gobject.
  GstAudioRingBufferSpec* gobj() { return m_spec; };

  /// Gets the underlying gobject.
  const GstAudioRingBufferSpec* gobj() const { return m_spec; };

  /** Get the caps of the buffer (in). */
  Glib::RefPtr<Gst::Caps> get_caps();
  Glib::RefPtr<const Gst::Caps> get_caps() const;

  /** Set the caps of the buffer (in). */
  void set_caps(const Glib::RefPtr<Gst::Caps>& value);

  /** Get the sample type (in/out).
   */
  Gst::AudioRingBufferFormatType get_type() const;

  /** Set the sample type (in/out).
   */
  void set_type(const Gst::AudioRingBufferFormatType& value);

  /** Get the latency in microseconds (in/out).
   */
  guint64 get_latency_time() const;

  /** Set the latency in microseconds (in/out).
   */
  void set_latency_time(const guint64& value);

  /** Get the total buffer size in microseconds (in/out).
   */
  guint64 get_buffer_time() const;

  /** Set the total buffer size in microseconds (in/out).
   */
  void set_buffer_time(const guint64& value);

  /** Get the size of one segment in bytes (in/out).
   */
  int get_segsize() const;

  /** Set the size of one segment in bytes (in/out).
   */
  void set_segsize(const int& value);

  /** Get the total number of segments (in/out).
   */
  int get_segtotal() const;

  /** Set the total number of segments (in/out).
   */
  void set_segtotal(const int& value);

  /** Get the number of segments queued in the lower level device, defaults to
   * segtotal (in/out).
   */
  int get_seglatency() const;

  /** Set the number of segments queued in the lower level device, defaults to
   * segtotal (in/out).
   */
  void set_seglatency(const int& value);

 
protected:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
  GstAudioRingBufferSpec* m_spec;
  // Tells whether the m_spec member should be freed upon destruction.
  bool take_ownership;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


};

/** A base class for audio audioringbuffer implementations.
 * This object is the base class for audio ringbuffers used by the base audio
 * source and sink classes.
 *
 * The audioringbuffer abstracts a circular buffer of data. One reader and one
 * writer can operate on the data from different threads in a lockfree manner.
 * The base class is sufficiently flexible to be used as an abstraction for
 * DMA based audioringbuffer as well as a pure software implementations.
 *
 * Last reviewed on 2016-04-23 (1.8.0).
 * @ingroup GstBaseClasses
 */

class AudioRingBuffer : public Gst::Object
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  using CppObjectType = AudioRingBuffer;
  using CppClassType = AudioRingBuffer_Class;
  using BaseObjectType = GstAudioRingBuffer;
  using BaseClassType = GstAudioRingBufferClass;

  // noncopyable
  AudioRingBuffer(const AudioRingBuffer&) = delete;
  AudioRingBuffer& operator=(const AudioRingBuffer&) = delete;

private:  friend class AudioRingBuffer_Class;
  static CppClassType audioringbuffer_class_;

protected:
  explicit AudioRingBuffer(const Glib::ConstructParams& construct_params);
  explicit AudioRingBuffer(GstAudioRingBuffer* castitem);

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:

  AudioRingBuffer(AudioRingBuffer&& src) noexcept;
  AudioRingBuffer& operator=(AudioRingBuffer&& src) noexcept;

  ~AudioRingBuffer() noexcept override;

  /** Get the GType for this class, for use with the underlying GObject type system.
   */
  static GType get_type()      G_GNUC_CONST;

#ifndef DOXYGEN_SHOULD_SKIP_THIS


  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  GstAudioRingBuffer*       gobj()       { return reinterpret_cast<GstAudioRingBuffer*>(gobject_); }

  ///Provides access to the underlying C GObject.
  const GstAudioRingBuffer* gobj() const { return reinterpret_cast<GstAudioRingBuffer*>(gobject_); }

  ///Provides access to the underlying C instance. The caller is responsible for unrefing it. Use when directly setting fields in structs.
  GstAudioRingBuffer* gobj_copy();

private:


public:
  /** For example,
   * bool on_fill(const Glib::RefPtr<Gst::AudioRingBuffer>& rbuf,
   * const std::vector<guint8>& data, guint len);.
   * This slot is set with set_fill_slot() and is called to fill the memory at
   * data with len bytes of samples.
   */
  typedef sigc::slot<void, const Glib::ArrayHandle<guint8>&, guint> SlotFill;

  //TODO: _MEMBER_GET(cond, cond, Glib::Cond, GCond*)

  /** Sets the given fill slot on the buffer. The slot will be called every
   * time a segment has been written to a device.
   *
   * MT safe.
   *
   * @param slot The fill slot to set.
   */
  void set_fill_slot(const SlotFill& slot);
  

  /** Allocate the resources for the ringbuffer. This function fills
   * in the data pointer of the ring buffer with a valid Gst::Buffer
   * to which samples can be written.
   * 
   * @param spec The specs of the buffer.
   * @return <tt>true</tt> if the device could be acquired, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool acquire(Gst::AudioRingBufferSpec& spec);
  
  /** Free the resources of the ringbuffer.
   * 
   * @return <tt>true</tt> if the device could be released, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool release();
  
  /** Check if the ringbuffer is acquired and ready to use.
   * 
   * @return <tt>true</tt> if the ringbuffer is acquired, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool is_acquired() const;
  
  /** Activate @a buf to start or stop pulling data.
   * 
   * MT safe.
   * 
   * @param active The new mode.
   * @return <tt>true</tt> if the device could be activated in the requested mode,
   * <tt>false</tt> on error.
   */
  bool activate(bool active);
  
  /** Check if @a buf is activated.
   * 
   * MT safe.
   * 
   * @return <tt>true</tt> if the device is active.
   */
  bool is_active() const;
  
  /** Start processing samples from the ringbuffer.
   * 
   * @return <tt>true</tt> if the device could be started, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool start();
  
  /** Pause processing samples from the ringbuffer.
   * 
   * @return <tt>true</tt> if the device could be paused, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool pause();
  
  /** Stop processing samples from the ringbuffer.
   * 
   * @return <tt>true</tt> if the device could be stopped, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool stop();
  
  /** Get the number of samples queued in the audio device. This is
   * usually less than the segment size but can be bigger when the
   * implementation uses another internal buffer between the audio
   * device.
   * 
   * For playback ringbuffers this is the amount of samples transfered from the
   * ringbuffer to the device but still not played.
   * 
   * For capture ringbuffers this is the amount of samples in the device that are
   * not yet transfered to the ringbuffer.
   * 
   * @return The number of samples queued in the audio device.
   * 
   * MT safe.
   */
  guint get_delay() const;
  
  /** Get the number of samples that were processed by the ringbuffer
   * since it was last started. This does not include the number of samples not
   * yet processed (see delay()).
   * 
   * @return The number of samples processed by the ringbuffer.
   * 
   * MT safe.
   */
  guint64 get_samples_done() const;
  
  /** Make sure that the next sample written to the device is
   * accounted for as being the @a sample sample written to the
   * device. This value will be used in reporting the current
   * sample position of the ringbuffer.
   * 
   * This function will also clear the buffer with silence.
   * 
   * MT safe.
   * 
   * @param sample The sample number to set.
   */
  void set_sample(guint64 sample);
  
  /** Tell the ringbuffer about the device's channel positions. This must
   * be called in when the ringbuffer is acquired.
   * 
   * @param position The device channel positions.
   */
  void set_channel_position(const Gst::AudioChannelPosition& position);
  
  /** Check if @a buf is flushing.
   * 
   * MT safe.
   * 
   * @return <tt>true</tt> if the device is flushing.
   */
  gboolean is_flushing();
  
  void set_timestamp(gint readseg, ClockTime timestamp);

 
  /** Commit @a in_samples samples pointed to by @a data to the ringbuffer @a buf.
   * 
   *  @a in_samples and @a out_samples define the rate conversion to perform on the
   * samples in @a data. For negative rates, @a out_samples must be negative and
   *  @a in_samples positive.
   * 
   * When @a out_samples is positive, the first sample will be written at position @a sample
   * in the ringbuffer. When @a out_samples is negative, the last sample will be written to
   *  @a sample in reverse order.
   * 
   *  @a out_samples does not need to be a multiple of the segment size of the ringbuffer
   * although it is recommended for optimal performance.
   * 
   *  @a accum will hold a temporary accumulator used in rate conversion and should be
   * set to 0 when this function is first called. In case the commit operation is
   * interrupted, one can resume the processing by passing the previously returned
   *  @a accum value back to this function.
   * 
   * MT safe.
   * 
   * @param sample The sample position of the data.
   * @param data The data to commit.
   * @param in_samples The number of samples in the data to commit.
   * @param out_samples The number of samples to write to the ringbuffer.
   * @param accum Accumulator for rate conversion.
   * @return The number of samples written to the ringbuffer or -1 on error. The
   * number of samples written can be less than @a out_samples when @a buf was interrupted
   * with a flush or stop.
   */
  guint commit(guint64& sample, const std::vector<guint8>& data, int in_samples, int out_samples, int& accum);

  
  /** Convert @a src_val in @a src_fmt to the equivalent value in @a dest_fmt. The result
   * will be put in @a dest_val.
   * 
   * @param src_fmt The source format.
   * @param src_val The source value.
   * @param dest_fmt The destination format.
   * @param dest_val A location to store the converted value.
   * @return <tt>true</tt> if the conversion succeeded.
   */
  bool convert(Gst::Format src_fmt, gint64 src_val, Gst::Format dest_fmt, gint64& dest_val) const;

  
  /** Returns a pointer to memory where the data from segment @a segment
   * can be found. This function is mostly used by subclasses.
   * 
   * @param segment The segment to read.
   * @param readptr The pointer to the memory where samples can be read.
   * @param len The number of bytes to read.
   * @return <tt>false</tt> if the buffer is not started.
   * 
   * MT safe.
   */

  bool prepare_read(int& segment, std::vector<guint8>& readptr, int& len);

  
  /** Read @a len samples from the ringbuffer into the memory pointed
   * to by @a data.
   * The first sample should be read from position @a sample in
   * the ringbuffer.
   * 
   *  @a len should not be a multiple of the segment size of the ringbuffer
   * although it is recommended.
   * 
   *  @a timestamp will return the timestamp associated with the data returned.
   * 
   * @param sample The sample position of the data.
   * @param data Where the data should be read.
   * @param len The number of samples in data to read.
   * @param timestamp Where the timestamp is returned.
   * @return The number of samples read from the ringbuffer or -1 on
   * error.
   * 
   * MT safe.
   */
  guint read(guint64 sample, const std::vector<guint8>& data, guint len, Gst::ClockTime& timestamp);

  
  /** Clear the given segment of the buffer with silence samples.
   * This function is used by subclasses.
   * 
   * MT safe.
   * 
   * @param segment The segment to clear.
   */
  void clear(int segment);
  
  /** Fill the ringbuffer with silence.
   * 
   * MT safe.
   */
  void clear_all();
  
  /** Subclasses should call this function to notify the fact that
   *  @a advance segments are now processed by the device.
   * 
   * MT safe.
   * 
   * @param advance The number of segments written.
   */
  void advance(guint advance);
  
  /** Close the audio device associated with the ring buffer. The ring buffer
   * should already have been released via release().
   * 
   * @return <tt>true</tt> if the device could be closed, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool close_device();
  
  /** Open the audio device associated with the ring buffer. Does not perform any
   * setup on the device. You must open the device before acquiring the ring
   * buffer.
   * 
   * @return <tt>true</tt> if the device could be opened, <tt>false</tt> on error.
   * 
   * MT safe.
   */
  bool open_device();
  
  /** Checks the status of the device associated with the ring buffer.
   * 
   * @return <tt>true</tt> if the device was open, <tt>false</tt> if it was closed.
   * 
   * MT safe.
   */
  bool device_is_open() const;
  
  /** Tell the ringbuffer that it is allowed to start playback when
   * the ringbuffer is filled with samples.
   * 
   * MT safe.
   * 
   * @param allowed The new value.
   */
  void set_may_start(bool allowed);
  
  /** Parse @a caps into @a p1.
   * 
   * @param p1 A spec.
   * @param caps A Gst::Caps.
   * @return <tt>true</tt> if the caps could be parsed.
   */
  static bool parse_caps(Gst::AudioRingBufferSpec& p1, const Glib::RefPtr<Gst::Caps>& caps);
  
  /** Set the ringbuffer to flushing mode or normal mode.
   * 
   * MT safe.
   * 
   * @param flushing The new mode.
   */
  void set_flushing(bool flushing);

  /** Virtual function to open the device.  Don't set any params or allocate
   * anything.
   */
    virtual bool open_device_vfunc();


  /** Virtual function to allocate the resources for the ring buffer using the
   * given spec.
   */
  virtual bool acquire_vfunc(Gst::AudioRingBufferSpec& spec);

  /** Virtual function to free resources of the ring buffer.
   */
    virtual bool release_vfunc();


  /** Virtual function to close the device.
   */
    virtual bool close_device_vfunc();


  /** Virtual function to start processing of samples.
   */
    virtual bool start_vfunc();


  /** Virtual function to pause processing of samples.
   */
    virtual bool pause_vfunc();


  /** Virtual function to resume processing of samples after pause.
   */
    virtual bool resume_vfunc();


  /** Virtual function to stop processing of samples.
   */
    virtual bool stop_vfunc();


  /** Virtual function to get number of samples queued in device.
   */
    virtual guint delay_vfunc();


  /** Virtual function to activate the thread that starts pulling and
   * monitoring the consumed segments in the device. Since 0.10.22.
   */
    virtual bool activate_vfunc(bool active);


  /** Virtual function to write samples into the ring buffer.
   */
  virtual guint commit_vfunc(guint64& sample, const std::vector<guint8>& data,
    int in_samples, int out_samples, int& accum);

  /** Virtual function to clear the entire audioringbuffer Since 0.10.24.
   */
    virtual void clear_all_vfunc();


protected:

  
#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:
  // todo this slot should be moved in move constructor, but for now it's
  // impossible to provide custom move constructor
  // (see https://bugzilla.gnome.org/show_bug.cgi?id=756593).
  // However, task should be managed by RefPtr class, so move constructor
  // and move assignment operator will never be called.
  std::unique_ptr<SlotFill> m_slot;
#endif


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::


};

} // namespace Gst


namespace Glib
{
  /** A Glib::wrap() method for this object.
   *
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Gst::AudioRingBuffer
   */
  Glib::RefPtr<Gst::AudioRingBuffer> wrap(GstAudioRingBuffer* object, bool take_copy = false);
}


#endif /* _GSTREAMERMM_AUDIORINGBUFFER_H */

