diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for essence-of-live-coding-pulse
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2019, Manuel Bärenz
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Manuel Bärenz nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/essence-of-live-coding-pulse.cabal b/essence-of-live-coding-pulse.cabal
new file mode 100644
--- /dev/null
+++ b/essence-of-live-coding-pulse.cabal
@@ -0,0 +1,39 @@
+name:                essence-of-live-coding-pulse
+version:             0.1.0.1
+synopsis: General purpose live coding framework - pulse backend
+description:
+  essence-of-live-coding is a general purpose and type safe live coding framework.
+  .
+  You can run programs in it, and edit, recompile and reload them while they're running.
+  Internally, the state of the live program is automatically migrated when performing hot code swap.
+  .
+  The library also offers an easy to use FRP interface.
+  It is parametrized by its side effects,
+  separates data flow cleanly from control flow,
+  and allows to develop live programs from reusable, modular components.
+  There are also useful utilities for debugging and quickchecking.
+  .
+  This package contains the backend for PulseAudio.
+
+license:             BSD3
+license-file:        LICENSE
+author:              Manuel Bärenz
+maintainer:          programming@manuelbaerenz.de
+homepage:            https://www.manuelbaerenz.de/#computerscience
+category:            FRP, Live coding
+build-type:          Simple
+extra-source-files:  CHANGELOG.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:
+    LiveCoding.Pulse
+    LiveCoding.Pulse.GHCi
+  build-depends:
+      base >= 4.11 && <4.13
+    , essence-of-live-coding
+    , transformers
+    , pulse-simple == 0.1.*
+    , foreign-store
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/LiveCoding/Pulse.hs b/src/LiveCoding/Pulse.hs
new file mode 100644
--- /dev/null
+++ b/src/LiveCoding/Pulse.hs
@@ -0,0 +1,96 @@
+{-# LANGUAGE Arrows #-}
+module LiveCoding.Pulse where
+
+-- base
+import Control.Arrow as X
+import Control.Concurrent
+import Control.Monad (forever)
+import Control.Monad.Fix
+
+-- transformers
+import Control.Monad.Trans.Reader
+
+-- pulse-simple
+import Sound.Pulse.Simple
+
+-- essence-of-live-coding
+import LiveCoding
+
+type PulseCell = Cell IO () Float
+
+playPulseCell :: PulseCell -> IO (MVar PulseCell)
+playPulseCell pulseCell = do
+  var <- newMVar pulseCell
+  pulseClient <- simpleNew
+    Nothing
+    "example"
+    Play
+    Nothing
+    "this is an example application"
+    (SampleSpec (F32 LittleEndian) 44100 1)
+    Nothing
+    Nothing
+  forkIO $ forever $ do
+    cell <- takeMVar var
+    (samples, cell') <- steps cell $ replicate 1024 ()
+    simpleWrite pulseClient samples
+    putMVar var cell'
+  return var
+
+-- TODO Generalisable
+updatePulse :: MVar PulseCell -> PulseCell -> IO ()
+updatePulse var newCell = do
+  oldCell <- takeMVar var
+  putMVar var $ hotCodeSwapCell newCell oldCell
+
+-- Returns the sum between -1 and 1
+wrapSum :: (Monad m, Data a, RealFloat a) => Cell m a a
+wrapSum = Cell
+  { cellState = 0
+  , cellStep  = \accum a ->
+    let
+        (_, accum')  = properFraction $ accum + a
+    in return (accum', accum')
+  }
+
+modSum :: (Monad m, Data a, Integral a) => a -> Cell m a a
+modSum denominator = Cell
+  { cellState = 0
+  , cellStep  = \accum a -> let accum' = (accum + a) `mod` denominator in return (accum', accum')
+  }
+
+
+clamp :: (Ord a, Num a) => a -> a -> a -> a
+clamp lower upper a = min upper $ max lower a
+
+osc :: (Data a, RealFloat a, MonadFix m) => Cell (ReaderT a m) () a
+osc = proc _ -> do
+  f <- constM ask -< ()
+  phase <- wrapSum -< f / 44100
+  returnA -< sin $ 2 * pi * phase
+
+osc' :: (Data a, RealFloat a, MonadFix m) => Cell m a a
+osc' = proc a -> do
+  runReaderC' osc -< (a, ())
+
+data Note
+  = A
+  | Bb
+  | B
+  | C
+  | Cis
+  | D
+  | Dis
+  | E
+  | F
+  | Fis
+  | G
+  | Gis
+  deriving (Enum, Show)
+
+f :: Note -> Float
+f note = 220 * (2 ** (fromIntegral (fromEnum note) / 12))
+
+o :: Float -> Float
+o = (* 2)
+
diff --git a/src/LiveCoding/Pulse/GHCi.hs b/src/LiveCoding/Pulse/GHCi.hs
new file mode 100644
--- /dev/null
+++ b/src/LiveCoding/Pulse/GHCi.hs
@@ -0,0 +1,29 @@
+module LiveCoding.Pulse.GHCi where
+
+-- base
+import Control.Concurrent
+
+-- foreign-store
+import Foreign.Store
+
+-- essence-of-live-coding
+import LiveCoding.LiveProgram
+
+-- essence-of-live-coding-pulse
+import LiveCoding.Pulse
+
+livepulse "" = livepulse "pulseCell"
+livepulse pulseCell = return $ unlines
+  [ "var <- playPulseCell " ++ pulseCell
+  , "savePulse var"
+  ]
+livereloadpulse "" = livereloadpulse "pulseCell"
+livereloadpulse pulseCell  = return $ unlines
+  [ ":reload"
+  , "var <- loadPulse"
+  , "updatePulse var " ++ pulseCell
+  ]
+loadPulse :: IO (MVar PulseCell)
+loadPulse = readStore (Store 0)
+savePulse :: MVar PulseCell -> IO ()
+savePulse var = writeStore (Store 0) var
