discord-haskell-voice-2.3.1: Voice support for discord-haskell.
Copyright(c) Yuto Takano (2021)
LicenseMIT
Maintainermoa17stock@gmail.com
Safe HaskellNone
LanguageHaskell2010

Discord.Voice.Conduit

Description

This module provides convenient Conduits (see the conduit package for an introduction to conduits, but essentially streaming pipes) for transforming audio data, to be used with the apostrophe-marked functions in Discord.Voice.

The apostrophe-marked functions, such as playFile', take as argument a Conduit of the following type:

ConduitT B.ByteString B.ByteString (ResourceT DiscordHandler) ()

That is, the Conduit's needs to take ByteString values from the upstream and give to the downstream, ByteStrings. This ByteString is formatted according to a 16-bit signed little-endian representation of PCM data, with a sample rate of 48kHz. Since ByteStrings are stored as Word8 (8-bits) internally, this module provides conduits to pack every two bytes into a single signed 16-bit Int16, and vice versa. See packInt16C and unpackInt16C.

Since the audio data is stereo, there are also conduits provided that pack to and unpack from tuples of (left, right) :: (Int16, Int16) values.

These enable us to have an easier type signature to work with when performing arithmetics on audio data:

yourConduit :: ConduitT Int16 Int16 (ResourceT DiscordHandler) ()

playYouTube' "never gonna give you up" $ packInt16C .| yourConduit .| unpackInt16C

Despite the pack/unpack being a common pattern, unfortunately due to library design, it is not the default behaviour for apostrophe-marked functions (the reason being that the non-apostrophe-marked-functions are simply aliases for the apostrophe ones but with a awaitForever yield conduit; this means adding pack/unpack to the apostrophe versions would slow down the streaming of untransformed data).

An example usage of these conduits is:

runVoice $ do
    join (read "123456789012345") (read "67890123456789012")
    playFile' "Lost in the Woods.mp3" $ packTo16CT .| toMono .| packFrom16CT
Synopsis

Conduits to transform ByteString into workable Int16 data

packInt16C :: ConduitT ByteString Int16 (ResourceT DiscordHandler) () Source #

A conduit that transforms 16-bit signed little-endian PCM ByteString to streams of Int16 values. The Int16 values are in the range [-32768, 32767] and alternate between left and right channels (stereo audio). See packInt16CT for a version that produces tuples for both channels.

packInt16CT :: ConduitT ByteString (Int16, Int16) (ResourceT DiscordHandler) () Source #

A conduit that transforms 16-bit signed little-endian PCM ByteString to streams of (left, right)-tupled Int16 values.

unpackInt16C :: ConduitT Int16 ByteString (ResourceT DiscordHandler) () Source #

A conduit that transforms streams of Int16 values to a ByteString, laid out in 16-bit little-endian PCM format. Alternating inputs to this conduit will be taken as left and right channels. See unpackInt16CT for a version that takes a stream of tuples of both channels.

unpackInt16CT :: ConduitT (Int16, Int16) ByteString (ResourceT DiscordHandler) () Source #

A conduit that transforms (left, right)-tupled Int16 values into 16-bit signed little-endian PCM ByteString.

Common audio operations exemplars (see source for inspiration)

toMono :: ConduitT (Int16, Int16) (Int16, Int16) (ResourceT DiscordHandler) () Source #

A conduit to transform stereo audio to mono audio by taking the average of the left and right channel values.