diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Anton Kholomiov 2010
+
+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 Anton Kholomiov 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/src/Temporal/Media.hs b/src/Temporal/Media.hs
new file mode 100644
--- /dev/null
+++ b/src/Temporal/Media.hs
@@ -0,0 +1,449 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
+module Temporal.Media (
+	-- * Time classes
+	Dur(..), Temporal(..), Stretchable(..), 
+	ToMaybe(..), TemporalFunctor(..),
+	-- * Transformers
+	Reversible(..), Sliceable(..), cut, 
+	-- * Structure 
+	Construct(..), Arrangeable(..),	Controlable(..),
+	sequent, parallel, loop, delay, temp,
+	-- * Media
+	Media(..), fold, fromMedia,
+	-- * Simple interperetation
+	-- ** Event list
+	Event, EventList(..), 
+	mapEvent, toEvent, toEventList,
+	-- ** Unit Temporal Media
+	MediaUnit(..), unMediaUnit, foldU, fromMediaUnit,
+	Unit(..)
+)
+where
+
+import Control.Applicative
+import Control.Monad
+
+import Data.Function
+import Data.Ratio
+
+import Prelude hiding (reverse, take, drop)
+import qualified Prelude as P (reverse)
+
+-------------------------------------------------
+-- Classes
+--
+-------------------------------------------------
+-- Time classes
+
+-- | time class
+class (Num t, Ord t, Fractional t) => Dur t
+
+instance Dur Double
+instance Integral a => Dur (Ratio a)
+
+-- | Temporal structures
+class Dur t => Temporal t a where
+	none    :: t -> a        -- ^ absence of value
+	dur     :: a -> t        -- ^ duration of value            
+
+-- | Stretching values by given time-factor
+class Dur t => Stretchable t a where
+	stretch :: t -> a -> a       
+
+-- | Values covertible to 'Maybe'	
+--
+--  auxiliary class for conversion to 'EventList'
+class ToMaybe m where
+	toMaybe :: m a -> Maybe a
+
+-- | temporal map
+class Dur t => TemporalFunctor t f where
+	tmap :: (t -> a -> b) -> f a -> f b
+
+---------------------------------------------------
+-- transformers
+--
+
+class Reversible a where
+	reverse :: a -> a
+
+-- | extracting parts, minimal complete definition:  'slice'.
+class Temporal t a => Sliceable t a where
+	slice :: t -> t -> a -> a   -- ^ @slice t0 t1 v@ extracts part of @v@ inside @[t0, t1]@
+	take  :: t -> a -> a        
+	drop  :: t -> a -> a
+
+	take t   = slice 0 t
+	drop t x = slice t (dur x) x
+
+sliceErrorMessage = error "should be t0 <= t1, for slice t0 t1" 
+
+-- | mixing slice and reverse. 
+--
+-- @cut t0 t1 v@ - if @t1 < t0@ reverses result of 'slice'
+cut :: (Reversible a, Sliceable t a) => t -> t -> a -> a
+cut t0 t1 m
+	| t0 <= t1  = slice t0 t1 m
+	| otherwise = slice (tm - t0) (tm - t1) $ reverse m
+	where tm = dur m
+
+----------------------------------------------------
+-- Structure
+--
+
+-- | constructor for generic structures
+class Construct m where
+	prim :: a -> m a
+
+-- | composing structures in sequent and parallel ways 
+class Arrangeable a where
+	(+:+) :: a -> a -> a
+	(=:=) :: a -> a -> a
+
+-- | modifer
+class Controlable c a where
+	control :: c -> a -> a
+	
+
+sequent, parallel :: Arrangeable a => [a] -> a
+
+sequent  = foldl1 (+:+)
+parallel = foldl1 (=:=)
+
+loop :: Arrangeable a => Int -> a -> a
+loop n = sequent . replicate n 
+
+delay :: (Temporal t a, Arrangeable a) => t -> a -> a
+delay t x = none t +:+ x
+
+
+-- | constructs generic temporal structure @m a@ form time @t@ and initial value @a@
+temp :: (Construct m, Temporal t (m a), Stretchable t (m a))
+	=> t -> a -> m a
+temp t = stretch t . prim
+
+
+----------------------------------------------------
+-- Media
+
+-- | Data type to represent temporal media
+data Media c a = Prim a                        -- ^ single value
+	       | Media c a :+: Media c a       -- ^ sequential composition
+	       | Media c a :=: Media c a       -- ^ parallel composition
+	       | Control c (Media c a)         -- ^ specific environment modifier
+		deriving (Show, Eq)
+
+
+-- | Folding Media
+--
+-- > fold prim seq par mod x
+--
+-- * prim - responds to 'Prim'
+--
+-- * seq  - responds to ':+:'
+--
+-- * par  - responds to ':=:'
+--
+-- * mod  - responds to 'Control'
+fold :: (a -> b) -> (b -> b -> b) -> (b -> b -> b) -> (c -> b -> b) 
+	-> Media c a -> b
+fold prim seq par mod m = 
+	case m of
+		Prim a      -> prim a
+		a :+: b     -> (seq `on` f) a b
+		a :=: b     -> (par `on` f) a b
+		Control c a -> mod c $ f a 
+	where f = fold prim seq par mod
+	
+
+
+instance Functor (Media c) where
+	fmap f x = case x of
+			Prim a      -> Prim $ f a
+			a :+: b     -> fmap f a :+: fmap f b
+			a :=: b     -> fmap f a :=: fmap f b
+			Control c a -> Control c $ fmap f a
+
+instance Monad (Media c) where
+	return   = Prim
+	ma >>= f = case ma of
+			Prim a      -> f a
+			a :+: b     -> (a >>= f) :+: (b >>= f)
+			a :=: b     -> (a >>= f) :=: (b >>= f)
+			Control c a -> Control c $ a >>= f
+
+instance Applicative (Media c) where
+	pure  = return
+	(<*>) = ap
+
+
+-- time
+
+instance Temporal t a => Temporal t (Media c a) where
+	none      = Prim . none
+	dur       = fold dur (+) max (const id)
+
+instance Stretchable t a => Stretchable t (Media c a) where
+	stretch d = fmap $ stretch d
+
+
+-- transformers
+
+instance Reversible a => Reversible (Media c a) where
+	reverse x = case x of
+			Prim a      -> Prim $ reverse a
+			a :+: b     -> ((:+:) `on` reverse) b a
+			a :=: b     -> ((:=:) `on` reverse) a b
+			Control c a -> Control c $ reverse a
+
+
+instance Sliceable t a => Sliceable t (Media c a) where
+	slice t0 t1 m 
+	    | t1 < t0   = sliceErrorMessage
+	    | t0 < 0    = none (abs t0) :+: slice 0 t1 m
+	    | t1 > tm   = slice t0 tm m :+: none (t1 - tm)
+	    | otherwise = case m of
+		    		Prim a      -> Prim $ slice t0 t1 a
+		    		a :+: b     -> sliceSeq t0 t1 a b 
+				a :=: b     -> ((:=:) `on` slice t0 t1) a b
+				Control c a -> Control c $ slice t0 t1 a
+		where tm = dur m
+
+sliceSeq :: Sliceable t a => t -> t -> Media c a -> Media c a -> Media c a
+sliceSeq t0 t1 a b
+	| t1 <= ta  = slice t0 t1 a
+	| t0 >= ta  = slice (t0 - ta) (t1 - ta) b
+	| otherwise = slice t0 ta a :+: slice 0 (t1 - ta) b
+	where ta = dur a
+
+	
+-- Structure
+
+instance Construct (Media c) where
+	prim = Prim
+
+instance Arrangeable (Media c a) where
+	(+:+) = (:+:)
+	(=:=) = (:=:)
+
+instance Controlable c (Media c a) where
+	control = Control
+
+----------------------------------------------------
+-- Meaning
+
+-- | Media imterpretation
+--
+-- given two functions (to convert elementary value @(a -> b)@, 
+-- and to convert modifiers @(c -> b -> b)@) `fromMedia` interprets 'Media' structure
+fromMedia :: Arrangeable b => (a -> b) -> (c -> b -> b) -> Media c a -> b
+fromMedia prim mod = fold prim (+:+) (=:=) mod
+	
+--------------------------------------------------------------------------------------	
+-- | Event type
+--
+-- @(t, dt, a)@ - value @a@ starts at @t@ and lasts for @dt@
+type Event t a = (t, t, a)
+
+-- | list of events with given total time
+data EventList t a = EventList t [Event t a]
+	deriving (Show, Eq)
+
+
+toEvent :: (Temporal t (m a), ToMaybe m) => m a -> EventList t a
+toEvent a = EventList (dur a) $ maybe [] (return . singleEvent) $ toMaybe a
+	where singleEvent x = (0, dur a, x)
+
+mapEvent :: Dur t => (a -> b) -> Event t a -> Event t b
+mapEvent f (t, dt, a) = (t, dt, f a)
+
+instance Dur t => Functor (EventList t) where
+	fmap f (EventList t es) = EventList t $ fmap (mapEvent f) es
+
+-- time
+
+instance Dur t => Temporal t (EventList t a) where
+	none t = EventList t []
+	dur (EventList t _) = t
+
+instance (Dur t, Stretchable t a) => Stretchable t (EventList t a) where
+	stretch d (EventList t es) = EventList (d * t) $ map (stretchEvent d) es
+		where stretchEvent d (t, dt, a) = (d * t, d * dt, stretch d a)
+
+instance Dur t => TemporalFunctor t (EventList t) where
+	tmap f (EventList t es) = EventList t $ map (tmapEvent f) es
+		where tmapEvent f (t, dt, a) = (t, dt, f dt a)
+
+-- structure
+
+instance Dur t => Construct (EventList t) where
+	prim a = EventList 1 [(0, 1, a)]
+
+instance Dur t => Arrangeable (EventList t a) where
+	(EventList t es) +:+ (EventList t' es') = 
+		EventList (t + t') (es ++ map (delayEvent t) es')
+		where delayEvent d (t, dt, a) = (t + d, dt, a)
+	(EventList t es) =:= (EventList t' es') =
+		EventList (max t t') $ merge es es'
+		where merge []  x = x
+		      merge x  [] = x
+                      merge (a@(ta, _, _):as) (b@(tb, _, _):bs) 
+			| ta < tb   = a : merge as     (b:bs)
+			| otherwise = b : merge (a:as) bs
+
+instance Dur t => Controlable () (EventList t a) where
+	control = const id
+
+-- meaning
+
+-- | converting to 'EventList'
+--
+-- 'toEventList' mapps generic temporal value @(m a)@ that can be 
+-- represented with @(t, Maybe a)@ to 'EventList' 
+toEventList :: (Temporal t (m a), ToMaybe m) 
+	=> (c -> EventList t a -> EventList t a) 
+	-> Media c (m a) -> EventList t a
+toEventList = fromMedia toEvent
+
+-------------------------------------------------------------------------
+-------------------------------------------------------------------
+-- Special case : Media with explicit time. Value is unit 
+--
+
+-- | Media with explicit time
+--
+-- Value is unit (undividable, invariant to reverse and time stretching) 
+-- O(1) 'dur'
+data Dur t => MediaUnit t c a = MediaUnit t (Media c (Unit t a))
+
+unMediaUnit :: Dur t => MediaUnit t c a -> Media c (Unit t a)
+unMediaUnit (MediaUnit _ m) = m
+
+
+instance Dur t => Functor (MediaUnit t c) where
+	fmap f (MediaUnit t m) = MediaUnit t $ fmap (fmap f) m
+
+
+instance Dur t => Monad (MediaUnit t c) where
+	return = MediaUnit 1 . return . return
+	(MediaUnit t ma) >>= f = MediaUnit (dur ma') ma'
+		where ma' = ft =<< ma
+                      ft ta = case unMediaUnit . f <$> ta of
+				(Unit t (Just a)) -> stretch t a
+				(Unit t Nothing)  -> none t 
+
+instance Dur t => Applicative (MediaUnit t c) where
+	pure  = return
+	(<*>) = ap
+
+
+-- time 
+
+instance Dur t => Temporal t (MediaUnit t c a) where
+	none t              = MediaUnit t $ none t     
+	dur (MediaUnit t _) = t
+
+instance Dur t => Stretchable t (MediaUnit t c a) where
+	stretch d (MediaUnit t m) = MediaUnit (t * d) $ stretch d m
+
+
+instance Dur t => TemporalFunctor t (MediaUnit t c) where
+	tmap f (MediaUnit t m) = MediaUnit t $ fmap (tmap f) m 
+
+-- transformers
+
+-- | 'fold' replica for MediaUnit
+foldU :: Dur t => (t -> a -> b) -> (b -> b -> b) -> (b -> b -> b) -> (c -> b -> b)
+	       -> MediaUnit t c a -> Maybe b
+foldU prim seq par mod = fold prim' (liftA2 seq) (liftA2 par) mod' . unMediaUnit
+	where prim' (Unit t a) = prim t <$> a
+	      mod' c = fmap (mod c)
+	     	
+
+instance Dur t => Reversible (MediaUnit t c a) where
+	reverse (MediaUnit t m) = MediaUnit t $ reverse $ m
+
+instance Dur t => Sliceable t (MediaUnit t c a) where
+	slice t0 t1 (MediaUnit t a) = MediaUnit (t1 - t0) $ slice t0 t1 a
+
+-- Structure
+
+instance Dur t => Construct (MediaUnit t c) where
+	prim = MediaUnit 1 . prim . prim
+
+instance Dur t => Arrangeable (MediaUnit t c a) where
+	a +:+ b = MediaUnit (dur a + dur b) $ (unMediaUnit a) +:+ (unMediaUnit b)
+	a =:= b 
+	     | ta < tb   = f tb (a' +:+ none (tb - ta)) b'
+	     | ta > tb   = f ta (b' +:+ none (ta - tb)) a'
+	     | otherwise = f ta a' b'
+		where ta = dur a
+		      tb = dur b
+		      a' = unMediaUnit a
+		      b' = unMediaUnit b
+		      f t a b = MediaUnit t $ a =:= b
+
+instance Dur t => Controlable c (MediaUnit t c a) where
+	control c (MediaUnit t a) = MediaUnit t $ control c a
+
+-- meaning
+
+-- | Interpretation of 'MediaUnit'
+--
+-- it relies on properties of 'Unit' (it's temporal and covertible to 'Maybe')
+fromMediaUnit :: Dur t => (c -> EventList t a -> EventList t a) 
+	-> MediaUnit t c a -> EventList t a
+fromMediaUnit f = toEventList f . unMediaUnit
+
+------------------------------------------------------------
+-- Unit
+
+-- | unit values that can happen and lasts for some time
+data Dur t => Unit t a = Unit t (Maybe a)
+	deriving (Show, Eq)
+
+instance Dur t => Functor (Unit t) where
+	fmap f (Unit t a) = Unit t $ fmap f a
+
+instance Dur t => Monad (Unit t) where
+	return   = prim 
+	(Unit t a) >>= f = case fmap f a of
+				Nothing         -> none t
+				Just (Unit t' b) -> Unit (t * t') b
+
+instance Dur t => Applicative (Unit t) where
+	pure  = return
+	(<*>) = ap
+
+-- time 
+
+instance Dur t => Temporal t (Unit t a) where
+	none t = Unit t Nothing
+	dur (Unit t _) = t
+
+instance Dur t => Stretchable t (Unit t a) where
+	stretch d (Unit t a) = Unit (d * t) a
+
+instance Dur t => ToMaybe (Unit t) where
+	toMaybe (Unit _ a) = a
+
+instance Dur t => TemporalFunctor t (Unit t) where
+	tmap f (Unit t a) = Unit t $ fmap (f t) a
+
+-- Unit transformers
+
+instance Dur t => Reversible (Unit t a) where
+	reverse = id
+
+instance Dur t => Sliceable t (Unit t a) where
+	slice t0 t1 u@(Unit t a) 
+		| t1 < t0          = sliceErrorMessage
+		| t1 < (t - eps) || t0 > eps = none $ t1 - t0 
+		| otherwise        = u
+		where eps = 1e-6 
+
+-- structure
+
+instance Dur t => Construct (Unit t) where
+	prim a = Unit 1 $ Just a
+
diff --git a/src/Temporal/Media/Double.hs b/src/Temporal/Media/Double.hs
new file mode 100644
--- /dev/null
+++ b/src/Temporal/Media/Double.hs
@@ -0,0 +1,114 @@
+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-}
+-- | Special case of "Temporal.Media". Time is @Double@
+module Temporal.Media.Double (
+	-- * Time classes
+	Dur, none, dur, stretch, ToMaybe(..), tmap,
+	-- * Transformers
+	Reversible(..), slice, take, drop, cut, 
+	-- * Structure 
+	Construct(..), Arrangeable(..), Controlable(..),
+	sequent, parallel, loop, delay, temp,
+	-- * Media
+	Media(..), fold, fromMedia,
+	-- * Simple interperetation
+	-- ** Event list
+	Event, EventList(..), 
+	mapEvent, toEvent, toEventList,
+	-- ** Unit Media
+	MediaUnit(..), unMediaUnit, foldU, fromMediaUnit,
+	Unit(..)
+) 
+where
+
+import Prelude hiding (take, drop, reverse)
+import Control.Applicative
+
+import qualified Temporal.Media as M
+import Temporal.Media (
+	ToMaybe(..),
+	Reversible(..), 
+	Construct(..), Arrangeable(..), Controlable(..), 
+	sequent, parallel, loop,
+	Media(..), fold, fromMedia)
+
+----------------------------------------
+-- Time 
+--
+
+type Dur = Double
+
+none :: M.Temporal Dur a => Dur -> a
+none = M.none
+
+dur :: M.Temporal Dur a => a -> Dur
+dur = M.dur
+
+stretch :: M.Stretchable Dur a => Dur -> a -> a
+stretch = M.stretch
+
+tmap :: M.TemporalFunctor Dur f => (Dur -> a -> b) -> (f a -> f b)
+tmap = M.tmap
+
+--------------------------------------------
+-- transformers
+
+slice :: M.Sliceable Dur a => Dur -> Dur -> a -> a
+slice = M.slice
+
+take :: M.Sliceable Dur a => Dur -> a -> a
+take = M.take
+
+drop :: M.Sliceable Dur a => Dur -> a -> a
+drop = M.drop
+
+cut :: (Reversible a, M.Sliceable Dur a) => Dur -> Dur -> a -> a
+cut = M.cut
+
+--------------------------------------------
+-- Structure
+
+delay :: (M.Temporal Dur a, Arrangeable a) => Dur -> a -> a
+delay = M.delay
+
+temp :: (Construct m, M.Temporal Dur (m a), M.Stretchable Dur (m a)) 
+	=> Dur -> a -> m a
+temp = M.temp
+	
+
+--------------------------------------------
+-- EventList
+
+type Event a     = M.Event Dur a
+type EventList a = M.EventList Dur a
+
+mapEvent :: (a -> b) -> Event a -> Event b
+mapEvent = M.mapEvent
+
+toEvent :: (M.Temporal Dur (m a), ToMaybe m) => m a -> EventList a
+toEvent = M.toEvent
+
+toEventList :: (M.Temporal Dur (m a), ToMaybe m) 
+	=> (c -> EventList a -> EventList a) 
+	-> Media c (m a) -> EventList a
+toEventList = M.toEventList
+
+--------------------------------------------
+-- MediaUnit
+
+type MediaUnit c a = M.MediaUnit Dur c a
+
+unMediaUnit :: MediaUnit c a -> Media c (Unit a)
+unMediaUnit = M.unMediaUnit
+
+foldU :: (Dur -> a -> b) -> (b -> b -> b) -> (b -> b -> b) -> (c -> b -> b)
+	-> MediaUnit c a -> Maybe b
+foldU = M.foldU
+
+fromMediaUnit :: (c -> EventList a -> EventList a) -> MediaUnit c a -> EventList a
+fromMediaUnit = M.fromMediaUnit
+
+--------------------------------------------
+-- Temp
+
+type Unit a = M.Unit Dur a
+
diff --git a/temporal-media.cabal b/temporal-media.cabal
new file mode 100644
--- /dev/null
+++ b/temporal-media.cabal
@@ -0,0 +1,28 @@
+Name:          temporal-media
+Version:       0.0
+License-file:  LICENSE
+Cabal-Version: >= 1.2
+License:       BSD3
+Author:	       Anton Kholomiov
+Maintainer:    <anton.kholomiov@gmail.com>
+Synopsis:      data types for temporal media
+Description:   
+      Ispired by the paper /An Algebraic Theory of Polymorphic Temporal Media/, 
+      Paul Hudak 
+      <http://haskell.cs.yale.edu/yale/papers/polymedia/hudak-RR-1259.pdf>, 
+      Haskore and Hommage
+
+Category:      Media, Music
+Stability:     Experimental
+Tested-With:   GHC==6.13.1
+Build-Type:    Simple
+
+
+Library
+  Build-Depends:
+        base >= 4, base < 5
+  Hs-Source-Dirs:      src/
+  Exposed-Modules:
+        Temporal.Media
+        Temporal.Media.Double
+
