module Data.MediaBus.Media.Buffer
( type CanBeSample
, HasMediaBuffer(..)
, type HasMediaBuffer'
, type HasMediaBufferL
, type HasMediaBufferL'
, mediaBuffer'
, MediaBuffer(..)
, mediaBufferVector
, mediaBufferLength
, mediaBufferFromList
, mediaBufferToList
, mediaBufferFromByteString
, mediaBufferToByteString
, createMediaBuffer
, modifyMediaBuffer
, unsafeModifyMediaBuffer
) where
import Control.DeepSeq
import Control.Lens
import Control.Monad.ST (ST, runST)
import qualified Data.ByteString as B
import Data.Default
import Data.MediaBus.Media.Samples
import Data.Typeable
import qualified Data.Vector.Storable as V
import qualified Data.Vector.Storable.ByteString as Spool
import GHC.Exts (IsList(..))
import GHC.Generics (Generic)
class HasMediaBuffer s t where
type MediaBufferFrom s
type MediaBufferTo t
mediaBuffer :: Lens s t (MediaBufferFrom s) (MediaBufferTo t)
type HasMediaBuffer' s = (HasMediaBuffer s s, MediaBufferFrom s ~ MediaBufferTo s)
mediaBuffer'
:: HasMediaBuffer' s
=> Lens' s (MediaBufferFrom s)
mediaBuffer' = mediaBuffer
type HasMediaBufferL s t a b = (HasMediaBuffer s t, MediaBufferFrom s ~ a, MediaBufferTo t ~ b)
type HasMediaBufferL' s a = (HasMediaBuffer s s, MediaBufferFrom s ~ a, MediaBufferTo s ~ a)
newtype MediaBuffer t = MkMediaBuffer
{ _mediaBufferVector :: V.Vector t
} deriving (Generic, NFData, Monoid, Eq)
mediaBufferVector :: Iso (MediaBuffer s) (MediaBuffer t) (V.Vector s) (V.Vector t)
mediaBufferVector = iso _mediaBufferVector MkMediaBuffer
instance (V.Storable a, V.Storable b) =>
Each (MediaBuffer a) (MediaBuffer b) a b where
each = mediaBufferVector . each
instance CanBeSample s =>
IsList (MediaBuffer s) where
type Item (MediaBuffer s) = s
fromList = mediaBufferFromList
toList = mediaBufferToList
instance (Show a, CanBeSample a) =>
Show (MediaBuffer a) where
showsPrec d m =
showParen (d > 10) $
showString "media buffer: " .
showsPrec 8 (mediaBufferLength m) .
showString " * " . showsPrec 8 (typeRep (Proxy :: Proxy a))
instance CanBeSample sampleType =>
Default (MediaBuffer sampleType) where
def = mempty
mediaBufferLength
:: CanBeSample t
=> MediaBuffer t -> Int
mediaBufferLength = view (mediaBufferVector . to V.length)
mediaBufferToList
:: CanBeSample s
=> MediaBuffer s -> [s]
mediaBufferToList = view (mediaBufferVector . to V.toList)
mediaBufferFromList
:: CanBeSample s
=> [s] -> MediaBuffer s
mediaBufferFromList = MkMediaBuffer . V.fromList
mediaBufferFromByteString
:: CanBeSample a
=> B.ByteString -> MediaBuffer a
mediaBufferFromByteString = MkMediaBuffer . Spool.byteStringToVector
mediaBufferToByteString
:: CanBeSample a
=> MediaBuffer a -> B.ByteString
mediaBufferToByteString = Spool.vectorToByteString . _mediaBufferVector
createMediaBuffer
:: CanBeSample t
=> (forall s. ST s (V.MVector s t)) -> MediaBuffer t
createMediaBuffer f = MkMediaBuffer (V.create f)
modifyMediaBuffer
:: CanBeSample a
=> (forall s. V.MVector s a -> ST s ()) -> MediaBuffer a -> MediaBuffer a
modifyMediaBuffer f = over mediaBufferVector (V.modify f)
unsafeModifyMediaBuffer
:: CanBeSample a
=> (forall s. V.MVector s a -> ST s r) -> MediaBuffer a -> (r, MediaBuffer a)
unsafeModifyMediaBuffer f (MkMediaBuffer !v) =
runST $ do
!mv <- V.unsafeThaw v
!r <- f mv
!v' <- V.unsafeFreeze mv
return (r, MkMediaBuffer v')