{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

A structure containing the result of an audio buffer map operation,
which is executed with 'GI.GstAudio.Structs.AudioBuffer.audioBufferMap'. For non-interleaved (planar)
buffers, the beginning of each channel in the buffer has its own pointer in
the /@planes@/ array. For interleaved buffers, the /@planes@/ array only contains
one item, which is the pointer to the beginning of the buffer, and /@nPlanes@/
equals 1.

The different channels in /@planes@/ are always in the GStreamer channel order.

/Since: 1.16/
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.GstAudio.Structs.AudioBuffer
    (

-- * Exported types
    AudioBuffer(..)                         ,
    newZeroAudioBuffer                      ,
    noAudioBuffer                           ,


 -- * Methods
-- ** clip #method:clip#

    audioBufferClip                         ,


-- ** map #method:map#

#if ENABLE_OVERLOADING
    AudioBufferMapMethodInfo                ,
#endif
    audioBufferMap                          ,


-- ** reorderChannels #method:reorderChannels#

    audioBufferReorderChannels              ,


-- ** truncate #method:truncate#

    audioBufferTruncate                     ,


-- ** unmap #method:unmap#

#if ENABLE_OVERLOADING
    AudioBufferUnmapMethodInfo              ,
#endif
    audioBufferUnmap                        ,




 -- * Properties
-- ** buffer #attr:buffer#
{- | the mapped buffer
-}
#if ENABLE_OVERLOADING
    audioBuffer_buffer                      ,
#endif
    clearAudioBufferBuffer                  ,
    getAudioBufferBuffer                    ,
    setAudioBufferBuffer                    ,


-- ** info #attr:info#
{- | a 'GI.GstAudio.Structs.AudioInfo.AudioInfo' describing the audio properties of this buffer
-}
#if ENABLE_OVERLOADING
    audioBuffer_info                        ,
#endif
    getAudioBufferInfo                      ,


-- ** nPlanes #attr:nPlanes#
{- | the number of planes available
-}
#if ENABLE_OVERLOADING
    audioBuffer_nPlanes                     ,
#endif
    getAudioBufferNPlanes                   ,
    setAudioBufferNPlanes                   ,


-- ** nSamples #attr:nSamples#
{- | the size of the buffer in samples
-}
#if ENABLE_OVERLOADING
    audioBuffer_nSamples                    ,
#endif
    getAudioBufferNSamples                  ,
    setAudioBufferNSamples                  ,


-- ** planes #attr:planes#
{- | an array of /@nPlanes@/ pointers pointing to the start of each
  plane in the mapped buffer
-}
#if ENABLE_OVERLOADING
    audioBuffer_planes                      ,
#endif
    clearAudioBufferPlanes                  ,
    getAudioBufferPlanes                    ,
    setAudioBufferPlanes                    ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import qualified GI.Gst.Flags as Gst.Flags
import qualified GI.Gst.Structs.Buffer as Gst.Buffer
import qualified GI.Gst.Structs.Segment as Gst.Segment
import {-# SOURCE #-} qualified GI.GstAudio.Enums as GstAudio.Enums
import {-# SOURCE #-} qualified GI.GstAudio.Structs.AudioInfo as GstAudio.AudioInfo

-- | Memory-managed wrapper type.
newtype AudioBuffer = AudioBuffer (ManagedPtr AudioBuffer)
instance WrappedPtr AudioBuffer where
    wrappedPtrCalloc = callocBytes 1288
    wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 1288 >=> wrapPtr AudioBuffer)
    wrappedPtrFree = Just ptr_to_g_free

-- | Construct a `AudioBuffer` struct initialized to zero.
newZeroAudioBuffer :: MonadIO m => m AudioBuffer
newZeroAudioBuffer = liftIO $ wrappedPtrCalloc >>= wrapPtr AudioBuffer

instance tag ~ 'AttrSet => Constructible AudioBuffer tag where
    new _ attrs = do
        o <- newZeroAudioBuffer
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `AudioBuffer`.
noAudioBuffer :: Maybe AudioBuffer
noAudioBuffer = Nothing

{- |
Get the value of the “@info@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' audioBuffer #info
@
-}
getAudioBufferInfo :: MonadIO m => AudioBuffer -> m GstAudio.AudioInfo.AudioInfo
getAudioBufferInfo s = liftIO $ withManagedPtr s $ \ptr -> do
    let val = ptr `plusPtr` 0 :: (Ptr GstAudio.AudioInfo.AudioInfo)
    val' <- (newBoxed GstAudio.AudioInfo.AudioInfo) val
    return val'

#if ENABLE_OVERLOADING
data AudioBufferInfoFieldInfo
instance AttrInfo AudioBufferInfoFieldInfo where
    type AttrAllowedOps AudioBufferInfoFieldInfo = '[ 'AttrGet]
    type AttrSetTypeConstraint AudioBufferInfoFieldInfo = (~) (Ptr GstAudio.AudioInfo.AudioInfo)
    type AttrBaseTypeConstraint AudioBufferInfoFieldInfo = (~) AudioBuffer
    type AttrGetType AudioBufferInfoFieldInfo = GstAudio.AudioInfo.AudioInfo
    type AttrLabel AudioBufferInfoFieldInfo = "info"
    type AttrOrigin AudioBufferInfoFieldInfo = AudioBuffer
    attrGet _ = getAudioBufferInfo
    attrSet _ = undefined
    attrConstruct = undefined
    attrClear _ = undefined

audioBuffer_info :: AttrLabelProxy "info"
audioBuffer_info = AttrLabelProxy

#endif


{- |
Get the value of the “@n_samples@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' audioBuffer #nSamples
@
-}
getAudioBufferNSamples :: MonadIO m => AudioBuffer -> m Word64
getAudioBufferNSamples s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 320) :: IO Word64
    return val

{- |
Set the value of the “@n_samples@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' audioBuffer [ #nSamples 'Data.GI.Base.Attributes.:=' value ]
@
-}
setAudioBufferNSamples :: MonadIO m => AudioBuffer -> Word64 -> m ()
setAudioBufferNSamples s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 320) (val :: Word64)

#if ENABLE_OVERLOADING
data AudioBufferNSamplesFieldInfo
instance AttrInfo AudioBufferNSamplesFieldInfo where
    type AttrAllowedOps AudioBufferNSamplesFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint AudioBufferNSamplesFieldInfo = (~) Word64
    type AttrBaseTypeConstraint AudioBufferNSamplesFieldInfo = (~) AudioBuffer
    type AttrGetType AudioBufferNSamplesFieldInfo = Word64
    type AttrLabel AudioBufferNSamplesFieldInfo = "n_samples"
    type AttrOrigin AudioBufferNSamplesFieldInfo = AudioBuffer
    attrGet _ = getAudioBufferNSamples
    attrSet _ = setAudioBufferNSamples
    attrConstruct = undefined
    attrClear _ = undefined

audioBuffer_nSamples :: AttrLabelProxy "nSamples"
audioBuffer_nSamples = AttrLabelProxy

#endif


{- |
Get the value of the “@n_planes@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' audioBuffer #nPlanes
@
-}
getAudioBufferNPlanes :: MonadIO m => AudioBuffer -> m Int32
getAudioBufferNPlanes s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 328) :: IO Int32
    return val

{- |
Set the value of the “@n_planes@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' audioBuffer [ #nPlanes 'Data.GI.Base.Attributes.:=' value ]
@
-}
setAudioBufferNPlanes :: MonadIO m => AudioBuffer -> Int32 -> m ()
setAudioBufferNPlanes s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 328) (val :: Int32)

#if ENABLE_OVERLOADING
data AudioBufferNPlanesFieldInfo
instance AttrInfo AudioBufferNPlanesFieldInfo where
    type AttrAllowedOps AudioBufferNPlanesFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint AudioBufferNPlanesFieldInfo = (~) Int32
    type AttrBaseTypeConstraint AudioBufferNPlanesFieldInfo = (~) AudioBuffer
    type AttrGetType AudioBufferNPlanesFieldInfo = Int32
    type AttrLabel AudioBufferNPlanesFieldInfo = "n_planes"
    type AttrOrigin AudioBufferNPlanesFieldInfo = AudioBuffer
    attrGet _ = getAudioBufferNPlanes
    attrSet _ = setAudioBufferNPlanes
    attrConstruct = undefined
    attrClear _ = undefined

audioBuffer_nPlanes :: AttrLabelProxy "nPlanes"
audioBuffer_nPlanes = AttrLabelProxy

#endif


{- |
Get the value of the “@planes@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' audioBuffer #planes
@
-}
getAudioBufferPlanes :: MonadIO m => AudioBuffer -> m (Ptr ())
getAudioBufferPlanes s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 336) :: IO (Ptr ())
    return val

{- |
Set the value of the “@planes@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' audioBuffer [ #planes 'Data.GI.Base.Attributes.:=' value ]
@
-}
setAudioBufferPlanes :: MonadIO m => AudioBuffer -> Ptr () -> m ()
setAudioBufferPlanes s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 336) (val :: Ptr ())

{- |
Set the value of the “@planes@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #planes
@
-}
clearAudioBufferPlanes :: MonadIO m => AudioBuffer -> m ()
clearAudioBufferPlanes s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 336) (FP.nullPtr :: Ptr ())

#if ENABLE_OVERLOADING
data AudioBufferPlanesFieldInfo
instance AttrInfo AudioBufferPlanesFieldInfo where
    type AttrAllowedOps AudioBufferPlanesFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint AudioBufferPlanesFieldInfo = (~) (Ptr ())
    type AttrBaseTypeConstraint AudioBufferPlanesFieldInfo = (~) AudioBuffer
    type AttrGetType AudioBufferPlanesFieldInfo = Ptr ()
    type AttrLabel AudioBufferPlanesFieldInfo = "planes"
    type AttrOrigin AudioBufferPlanesFieldInfo = AudioBuffer
    attrGet _ = getAudioBufferPlanes
    attrSet _ = setAudioBufferPlanes
    attrConstruct = undefined
    attrClear _ = clearAudioBufferPlanes

audioBuffer_planes :: AttrLabelProxy "planes"
audioBuffer_planes = AttrLabelProxy

#endif


{- |
Get the value of the “@buffer@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' audioBuffer #buffer
@
-}
getAudioBufferBuffer :: MonadIO m => AudioBuffer -> m (Maybe Gst.Buffer.Buffer)
getAudioBufferBuffer s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 344) :: IO (Ptr Gst.Buffer.Buffer)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newBoxed Gst.Buffer.Buffer) val'
        return val''
    return result

{- |
Set the value of the “@buffer@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' audioBuffer [ #buffer 'Data.GI.Base.Attributes.:=' value ]
@
-}
setAudioBufferBuffer :: MonadIO m => AudioBuffer -> Ptr Gst.Buffer.Buffer -> m ()
setAudioBufferBuffer s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 344) (val :: Ptr Gst.Buffer.Buffer)

{- |
Set the value of the “@buffer@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #buffer
@
-}
clearAudioBufferBuffer :: MonadIO m => AudioBuffer -> m ()
clearAudioBufferBuffer s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 344) (FP.nullPtr :: Ptr Gst.Buffer.Buffer)

#if ENABLE_OVERLOADING
data AudioBufferBufferFieldInfo
instance AttrInfo AudioBufferBufferFieldInfo where
    type AttrAllowedOps AudioBufferBufferFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint AudioBufferBufferFieldInfo = (~) (Ptr Gst.Buffer.Buffer)
    type AttrBaseTypeConstraint AudioBufferBufferFieldInfo = (~) AudioBuffer
    type AttrGetType AudioBufferBufferFieldInfo = Maybe Gst.Buffer.Buffer
    type AttrLabel AudioBufferBufferFieldInfo = "buffer"
    type AttrOrigin AudioBufferBufferFieldInfo = AudioBuffer
    attrGet _ = getAudioBufferBuffer
    attrSet _ = setAudioBufferBuffer
    attrConstruct = undefined
    attrClear _ = clearAudioBufferBuffer

audioBuffer_buffer :: AttrLabelProxy "buffer"
audioBuffer_buffer = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList AudioBuffer
type instance O.AttributeList AudioBuffer = AudioBufferAttributeList
type AudioBufferAttributeList = ('[ '("info", AudioBufferInfoFieldInfo), '("nSamples", AudioBufferNSamplesFieldInfo), '("nPlanes", AudioBufferNPlanesFieldInfo), '("planes", AudioBufferPlanesFieldInfo), '("buffer", AudioBufferBufferFieldInfo)] :: [(Symbol, *)])
#endif

-- method AudioBuffer::map
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "buffer", argType = TInterface (Name {namespace = "GstAudio", name = "AudioBuffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to a #GstAudioBuffer", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "info", argType = TInterface (Name {namespace = "GstAudio", name = "AudioInfo"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the audio properties of the buffer", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "gstbuffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstBuffer to be mapped", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "flags", argType = TInterface (Name {namespace = "Gst", name = "MapFlags"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the access mode for the memory", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_audio_buffer_map" gst_audio_buffer_map ::
    Ptr AudioBuffer ->                      -- buffer : TInterface (Name {namespace = "GstAudio", name = "AudioBuffer"})
    Ptr GstAudio.AudioInfo.AudioInfo ->     -- info : TInterface (Name {namespace = "GstAudio", name = "AudioInfo"})
    Ptr Gst.Buffer.Buffer ->                -- gstbuffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    CUInt ->                                -- flags : TInterface (Name {namespace = "Gst", name = "MapFlags"})
    IO CInt

{- |
Maps an audio /@gstbuffer@/ so that it can be read or written and stores the
result of the map operation in /@buffer@/.

This is especially useful when the /@gstbuffer@/ is in non-interleaved (planar)
layout, in which case this function will use the information in the
/@gstbuffer@/\'s attached 'GI.GstAudio.Structs.AudioMeta.AudioMeta' in order to map each channel in a
separate \"plane\" in 'GI.GstAudio.Structs.AudioBuffer.AudioBuffer'. If a 'GI.GstAudio.Structs.AudioMeta.AudioMeta' is not attached
on the /@gstbuffer@/, then it must be in interleaved layout.

If a 'GI.GstAudio.Structs.AudioMeta.AudioMeta' is attached, then the 'GI.GstAudio.Structs.AudioInfo.AudioInfo' on the meta is checked
against /@info@/. Normally, they should be equal, but in case they are not,
a g_critical will be printed and the 'GI.GstAudio.Structs.AudioInfo.AudioInfo' from the meta will be
used.

In non-interleaved buffers, it is possible to have each channel on a separate
'GI.Gst.Structs.Memory.Memory'. In this case, each memory will be mapped separately to avoid
copying their contents in a larger memory area. Do note though that it is
not supported to have a single channel spanning over two or more different
'GI.Gst.Structs.Memory.Memory' objects. Although the map operation will likely succeed in this
case, it will be highly sub-optimal and it is recommended to merge all the
memories in the buffer before calling this function.

Note: The actual 'GI.Gst.Structs.Buffer.Buffer' is not ref\'ed, but it is required to stay valid
as long as it\'s mapped.

/Since: 1.16/
-}
audioBufferMap ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AudioBuffer
    {- ^ /@buffer@/: pointer to a 'GI.GstAudio.Structs.AudioBuffer.AudioBuffer' -}
    -> GstAudio.AudioInfo.AudioInfo
    {- ^ /@info@/: the audio properties of the buffer -}
    -> Gst.Buffer.Buffer
    {- ^ /@gstbuffer@/: the 'GI.Gst.Structs.Buffer.Buffer' to be mapped -}
    -> [Gst.Flags.MapFlags]
    {- ^ /@flags@/: the access mode for the memory -}
    -> m Bool
    {- ^ __Returns:__ 'True' if the map operation succeeded or 'False' on failure -}
audioBufferMap buffer info gstbuffer flags = liftIO $ do
    buffer' <- unsafeManagedPtrGetPtr buffer
    info' <- unsafeManagedPtrGetPtr info
    gstbuffer' <- unsafeManagedPtrGetPtr gstbuffer
    let flags' = gflagsToWord flags
    result <- gst_audio_buffer_map buffer' info' gstbuffer' flags'
    let result' = (/= 0) result
    touchManagedPtr buffer
    touchManagedPtr info
    touchManagedPtr gstbuffer
    return result'

#if ENABLE_OVERLOADING
data AudioBufferMapMethodInfo
instance (signature ~ (GstAudio.AudioInfo.AudioInfo -> Gst.Buffer.Buffer -> [Gst.Flags.MapFlags] -> m Bool), MonadIO m) => O.MethodInfo AudioBufferMapMethodInfo AudioBuffer signature where
    overloadedMethod _ = audioBufferMap

#endif

-- method AudioBuffer::unmap
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "buffer", argType = TInterface (Name {namespace = "GstAudio", name = "AudioBuffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GstAudioBuffer to unmap", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_audio_buffer_unmap" gst_audio_buffer_unmap ::
    Ptr AudioBuffer ->                      -- buffer : TInterface (Name {namespace = "GstAudio", name = "AudioBuffer"})
    IO ()

{- |
Unmaps an audio buffer that was previously mapped with
'GI.GstAudio.Structs.AudioBuffer.audioBufferMap'.

/Since: 1.16/
-}
audioBufferUnmap ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    AudioBuffer
    {- ^ /@buffer@/: the 'GI.GstAudio.Structs.AudioBuffer.AudioBuffer' to unmap -}
    -> m ()
audioBufferUnmap buffer = liftIO $ do
    buffer' <- unsafeManagedPtrGetPtr buffer
    gst_audio_buffer_unmap buffer'
    touchManagedPtr buffer
    return ()

#if ENABLE_OVERLOADING
data AudioBufferUnmapMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo AudioBufferUnmapMethodInfo AudioBuffer signature where
    overloadedMethod _ = audioBufferUnmap

#endif

-- method AudioBuffer::clip
-- method type : MemberFunction
-- Args : [Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The buffer to clip.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "segment", argType = TInterface (Name {namespace = "Gst", name = "Segment"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "Segment in %GST_FORMAT_TIME or %GST_FORMAT_DEFAULT to which\n          the buffer should be clipped.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "rate", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "sample rate.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "bpf", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "size of one audio frame in bytes. This is the size of one sample *\nnumber of channels.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "Buffer"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_audio_buffer_clip" gst_audio_buffer_clip ::
    Ptr Gst.Buffer.Buffer ->                -- buffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    Ptr Gst.Segment.Segment ->              -- segment : TInterface (Name {namespace = "Gst", name = "Segment"})
    Int32 ->                                -- rate : TBasicType TInt
    Int32 ->                                -- bpf : TBasicType TInt
    IO (Ptr Gst.Buffer.Buffer)

{- |
Clip the buffer to the given @/GstSegment/@.

After calling this function the caller does not own a reference to
/@buffer@/ anymore.
-}
audioBufferClip ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Gst.Buffer.Buffer
    {- ^ /@buffer@/: The buffer to clip. -}
    -> Gst.Segment.Segment
    {- ^ /@segment@/: Segment in 'GI.Gst.Enums.FormatTime' or 'GI.Gst.Enums.FormatDefault' to which
          the buffer should be clipped. -}
    -> Int32
    {- ^ /@rate@/: sample rate. -}
    -> Int32
    {- ^ /@bpf@/: size of one audio frame in bytes. This is the size of one sample *
number of channels. -}
    -> m Gst.Buffer.Buffer
    {- ^ __Returns:__ 'Nothing' if the buffer is completely outside the configured segment,
otherwise the clipped buffer is returned.

If the buffer has no timestamp, it is assumed to be inside the segment and
is not clipped -}
audioBufferClip buffer segment rate bpf = liftIO $ do
    buffer' <- B.ManagedPtr.disownBoxed buffer
    segment' <- unsafeManagedPtrGetPtr segment
    result <- gst_audio_buffer_clip buffer' segment' rate bpf
    checkUnexpectedReturnNULL "audioBufferClip" result
    result' <- (wrapBoxed Gst.Buffer.Buffer) result
    touchManagedPtr buffer
    touchManagedPtr segment
    return result'

#if ENABLE_OVERLOADING
#endif

-- method AudioBuffer::reorder_channels
-- method type : MemberFunction
-- Args : [Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The buffer to reorder.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "format", argType = TInterface (Name {namespace = "GstAudio", name = "AudioFormat"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The %GstAudioFormat of the buffer.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "channels", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The number of channels.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "from", argType = TCArray False (-1) 2 (TInterface (Name {namespace = "GstAudio", name = "AudioChannelPosition"})), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The channel positions in the buffer.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "to", argType = TCArray False (-1) 2 (TInterface (Name {namespace = "GstAudio", name = "AudioChannelPosition"})), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The channel positions to convert to.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : [Arg {argCName = "channels", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The number of channels.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "channels", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The number of channels.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_audio_buffer_reorder_channels" gst_audio_buffer_reorder_channels ::
    Ptr Gst.Buffer.Buffer ->                -- buffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    CUInt ->                                -- format : TInterface (Name {namespace = "GstAudio", name = "AudioFormat"})
    Int32 ->                                -- channels : TBasicType TInt
    Ptr CInt ->                             -- from : TCArray False (-1) 2 (TInterface (Name {namespace = "GstAudio", name = "AudioChannelPosition"}))
    Ptr CInt ->                             -- to : TCArray False (-1) 2 (TInterface (Name {namespace = "GstAudio", name = "AudioChannelPosition"}))
    IO CInt

{- |
Reorders /@buffer@/ from the channel positions /@from@/ to the channel
positions /@to@/. /@from@/ and /@to@/ must contain the same number of
positions and the same positions, only in a different order.
/@buffer@/ must be writable.
-}
audioBufferReorderChannels ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Gst.Buffer.Buffer
    {- ^ /@buffer@/: The buffer to reorder. -}
    -> GstAudio.Enums.AudioFormat
    {- ^ /@format@/: The @/GstAudioFormat/@ of the buffer. -}
    -> [GstAudio.Enums.AudioChannelPosition]
    {- ^ /@from@/: The channel positions in the buffer. -}
    -> [GstAudio.Enums.AudioChannelPosition]
    {- ^ /@to@/: The channel positions to convert to. -}
    -> m Bool
    {- ^ __Returns:__ 'True' if the reordering was possible. -}
audioBufferReorderChannels buffer format from to = liftIO $ do
    let channels = fromIntegral $ length to
    let from_expected_length_ = fromIntegral $ length from
    when (from_expected_length_ /= channels) $
        error "GstAudio.audioBufferReorderChannels : length of 'from' does not agree with that of 'to'."
    buffer' <- unsafeManagedPtrGetPtr buffer
    let format' = (fromIntegral . fromEnum) format
    let from' = map (fromIntegral . fromEnum) from
    from'' <- packStorableArray from'
    let to' = map (fromIntegral . fromEnum) to
    to'' <- packStorableArray to'
    result <- gst_audio_buffer_reorder_channels buffer' format' channels from'' to''
    let result' = (/= 0) result
    touchManagedPtr buffer
    freeMem from''
    freeMem to''
    return result'

#if ENABLE_OVERLOADING
#endif

-- method AudioBuffer::truncate
-- method type : MemberFunction
-- Args : [Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "The buffer to truncate.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything},Arg {argCName = "bpf", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "size of one audio frame in bytes. This is the size of one sample *\nnumber of channels.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "trim", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the number of samples to remove from the beginning of the buffer", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "samples", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the final number of samples that should exist in this buffer or -1\nto use all the remaining samples if you are only removing samples from the\nbeginning.", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "Buffer"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_audio_buffer_truncate" gst_audio_buffer_truncate ::
    Ptr Gst.Buffer.Buffer ->                -- buffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    Int32 ->                                -- bpf : TBasicType TInt
    Word64 ->                               -- trim : TBasicType TUInt64
    Word64 ->                               -- samples : TBasicType TUInt64
    IO (Ptr Gst.Buffer.Buffer)

{- |
Truncate the buffer to finally have /@samples@/ number of samples, removing
the necessary amount of samples from the end and /@trim@/ number of samples
from the beginning.

After calling this function the caller does not own a reference to
/@buffer@/ anymore.

/Since: 1.16/
-}
audioBufferTruncate ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Gst.Buffer.Buffer
    {- ^ /@buffer@/: The buffer to truncate. -}
    -> Int32
    {- ^ /@bpf@/: size of one audio frame in bytes. This is the size of one sample *
number of channels. -}
    -> Word64
    {- ^ /@trim@/: the number of samples to remove from the beginning of the buffer -}
    -> Word64
    {- ^ /@samples@/: the final number of samples that should exist in this buffer or -1
to use all the remaining samples if you are only removing samples from the
beginning. -}
    -> m Gst.Buffer.Buffer
    {- ^ __Returns:__ the truncated buffer or 'Nothing' if the arguments
  were invalid -}
audioBufferTruncate buffer bpf trim samples = liftIO $ do
    buffer' <- B.ManagedPtr.disownBoxed buffer
    result <- gst_audio_buffer_truncate buffer' bpf trim samples
    checkUnexpectedReturnNULL "audioBufferTruncate" result
    result' <- (wrapBoxed Gst.Buffer.Buffer) result
    touchManagedPtr buffer
    return result'

#if ENABLE_OVERLOADING
#endif

#if ENABLE_OVERLOADING
type family ResolveAudioBufferMethod (t :: Symbol) (o :: *) :: * where
    ResolveAudioBufferMethod "map" o = AudioBufferMapMethodInfo
    ResolveAudioBufferMethod "unmap" o = AudioBufferUnmapMethodInfo
    ResolveAudioBufferMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveAudioBufferMethod t AudioBuffer, O.MethodInfo info AudioBuffer p) => OL.IsLabel t (AudioBuffer -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif