diff --git a/Data/ZoomCache/PCM.hs b/Data/ZoomCache/PCM.hs
--- a/Data/ZoomCache/PCM.hs
+++ b/Data/ZoomCache/PCM.hs
@@ -6,12 +6,21 @@
 
     -- * Codec identifiers
     , pcmIdentifiers
+
+    , enumPCMDouble
+    , enumListPCMDouble
+    , enumSummaryPCMDouble
+    , wholeTrackSummaryPCMDouble
+
+    , enumSummaryListPCMDouble
+    , wholeTrackSummaryListPCMDouble
 ) where
 
 import Data.ByteString (ByteString)
 import Data.Int
 import Data.ZoomCache.Codec (Codec, identifyCodec)
 
+import Data.ZoomCache.PCM.Enumeratee
 import Data.ZoomCache.PCM.Types
 
 import Data.ZoomCache.PCM.IEEE754()
diff --git a/Data/ZoomCache/PCM/Enumeratee.hs b/Data/ZoomCache/PCM/Enumeratee.hs
new file mode 100644
--- /dev/null
+++ b/Data/ZoomCache/PCM/Enumeratee.hs
@@ -0,0 +1,206 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# OPTIONS -Wall #-}
+----------------------------------------------------------------------
+-- |
+-- Module      : Data.ZoomCache.PCM.Enumeratee
+-- Copyright   : Conrad Parker
+-- License     : BSD3-style (see LICENSE)
+--
+-- Maintainer  : Conrad Parker <conrad@metadecks.org>
+-- Stability   : unstable
+-- Portability : unknown
+--
+-- ZoomCache PCM enumeratee conversions
+----------------------------------------------------------------------
+
+module Data.ZoomCache.PCM.Enumeratee (
+      enumPCMDouble
+    , enumListPCMDouble
+
+    , enumSummaryPCMDouble
+    , wholeTrackSummaryPCMDouble
+
+    , enumSummaryListPCMDouble
+    , wholeTrackSummaryListPCMDouble
+) where
+
+import Control.Applicative ((<$>))
+import Control.Monad.Trans (MonadIO)
+import Data.ByteString (ByteString)
+import Data.Int
+import qualified Data.Iteratee as I
+import Data.Maybe
+import Data.Typeable
+import Data.TypeLevel.Num hiding ((==))
+import Data.ZoomCache
+import Data.ZoomCache.Codec
+import Data.ZoomCache.NList
+import Data.ZoomCache.Multichannel.NList
+
+import Data.ZoomCache.PCM.Types
+import Data.ZoomCache.PCM.IEEE754()
+import Data.ZoomCache.PCM.Int()
+
+----------------------------------------------------------------------
+
+rawToPCMDouble :: ZoomRaw -> [PCM Double]
+rawToPCMDouble (ZoomRaw xs) | typeOf xs == typeOf (undefined :: [PCM Double]) =
+                                 fromMaybe [] (cast xs :: Maybe [PCM Double])
+                            | typeOf xs == typeOf (undefined :: [PCM Float]) =
+                                            f (cast xs :: Maybe [PCM Float])
+                            | typeOf xs == typeOf (undefined :: [PCM Int]) =
+                                            f (cast xs :: Maybe [PCM Int])
+                            | typeOf xs == typeOf (undefined :: [PCM Int8]) =
+                                            f (cast xs :: Maybe [PCM Int8])
+                            | typeOf xs == typeOf (undefined :: [PCM Int16]) =
+                                            f (cast xs :: Maybe [PCM Int16])
+                            | typeOf xs == typeOf (undefined :: [PCM Int32]) =
+                                            f (cast xs :: Maybe [PCM Int32])
+                            | typeOf xs == typeOf (undefined :: [PCM Int64]) =
+                                            f (cast xs :: Maybe [PCM Int64])
+                            | otherwise = []
+    where
+        f :: Real a => Maybe [PCM a] -> [PCM Double]
+        f = maybe [] (map (PCM . realToFrac . unPCM))
+
+rawToListPCMDouble :: ZoomRaw -> [[PCM Double]]
+rawToListPCMDouble (ZoomRaw xs) | not (null d) = [d]
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Double)]) =
+                                                l (cast xs :: Maybe [NList D1 (PCM Double)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Float)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Float)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Int)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Int)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Int8)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Int8)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Int16)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Int16)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Int32)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Int32)])
+                                | typeOf xs == typeOf (undefined :: [NList D1 (PCM Int64)]) =
+                                                f (cast xs :: Maybe [NList D1 (PCM Int64)])
+                                | otherwise = []
+    where
+        d = rawToPCMDouble (ZoomRaw xs)
+        l :: Maybe [NList D1 a] -> [[a]]
+        l = maybe [] (map nListToList)
+        f :: (ZoomReadable a) => Maybe [NList D1 a] -> [[PCM Double]]
+        f = map (rawToPCMDouble . ZoomRaw) . l
+
+----------------------------------------------------------------------
+
+-- | Coercion of numeric Summary to type Summary Double.
+toSummaryPCMDouble :: Typeable a => Summary a -> Maybe (Summary (PCM Double))
+toSummaryPCMDouble s | typeOf s == typeOf (undefined :: Summary (PCM Double)) =
+                                   id (cast s :: Maybe (Summary (PCM Double)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Float)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Float)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Int)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Int)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Int8)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Int8)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Int16)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Int16)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Int32)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Int32)))
+                     | typeOf s == typeOf (undefined :: Summary (PCM Int64)) =
+                               sd <$> (cast s :: Maybe (Summary (PCM Int64)))
+                     | otherwise = Nothing
+    where
+        sd :: ZoomPCM a => Summary (PCM a) -> Summary (PCM Double)
+        sd s' = s' { summaryData = toSummaryDataPCMDouble (summaryData s') }
+
+toSummaryDataPCMDouble :: ZoomPCM a => SummaryData (PCM a) -> SummaryData (PCM Double)
+toSummaryDataPCMDouble s = pcmMkSummary
+    (realToFrac . pcmMin $ s)
+    (realToFrac . pcmMax $ s)
+    (pcmAvg s)
+    (pcmRMS s)
+
+toSummaryListPCMDouble :: Typeable a => Summary a -> Maybe [Summary (PCM Double)]
+toSummaryListPCMDouble s | isJust sd = (:[]) <$> sd
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Double))) =
+                                   sl <$> (cast s :: Maybe (Summary (NList D1 (PCM Double))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Float))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Float))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Int))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Int))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Int8))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Int8))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Int16))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Int16))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Int32))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Int32))))
+                         | typeOf s == typeOf (undefined :: Summary (NList D1 (PCM Int64))) =
+                                  sld <$> (cast s :: Maybe (Summary (NList D1 (PCM Int64))))
+                         | otherwise = Nothing
+    where
+        sd = toSummaryPCMDouble s
+        sl :: Summary (NList D1 a) -> [Summary a]
+        sl = summaryNListToList
+        sld :: Typeable a => Summary (NList D1 a) -> [Summary (PCM Double)]
+        sld = catMaybes . map toSummaryPCMDouble . sl
+
+----------------------------------------------------------------------
+
+enumPCMDouble :: (Functor m, MonadIO m)
+              => I.Enumeratee [Stream] [(TimeStamp, PCM Double)] m a
+enumPCMDouble = I.joinI . enumPackets . I.mapChunks (concatMap f)
+    where
+        f :: Packet -> [(TimeStamp, PCM Double)]
+        f Packet{..} = zip packetTimeStamps (rawToPCMDouble packetData)
+
+enumListPCMDouble :: (Functor m, MonadIO m)
+                  => I.Enumeratee [Stream] [(TimeStamp, [PCM Double])] m a
+enumListPCMDouble = I.joinI . enumPackets . I.mapChunks (concatMap f)
+    where
+        f :: Packet -> [(TimeStamp, [PCM Double])]
+        f Packet{..} = zip packetTimeStamps (rawToListPCMDouble packetData)
+
+----------------------------------------------------------------------
+
+-- | Read the summary of an entire track.
+wholeTrackSummaryPCMDouble :: (Functor m, MonadIO m)
+                           => [IdentifyCodec]
+                           -> TrackNo
+                           -> I.Iteratee ByteString m (Summary (PCM Double))
+wholeTrackSummaryPCMDouble identifiers trackNo = I.joinI $ enumCacheFile identifiers .
+    I.joinI . filterTracks [trackNo] .  I.joinI . e $ I.last
+    where
+        e = I.joinI . enumSummaries . I.mapChunks (catMaybes . map toSD)
+        toSD :: ZoomSummary -> Maybe (Summary (PCM Double))
+        toSD (ZoomSummary s) = toSummaryPCMDouble s
+
+enumSummaryPCMDouble :: (Functor m, MonadIO m)
+                     => Int
+                     -> I.Enumeratee [Stream] [Summary (PCM Double)] m a
+enumSummaryPCMDouble level =
+    I.joinI . enumSummaryLevel level .
+    I.mapChunks (catMaybes . map toSD)
+    where
+        toSD :: ZoomSummary -> Maybe (Summary (PCM Double))
+        toSD (ZoomSummary s) = toSummaryPCMDouble s
+
+-- | Read the summary of an entire track.
+wholeTrackSummaryListPCMDouble :: (Functor m, MonadIO m)
+                               => [IdentifyCodec]
+                               -> TrackNo
+                               -> I.Iteratee ByteString m [Summary (PCM Double)]
+wholeTrackSummaryListPCMDouble identifiers trackNo =
+    I.joinI $ enumCacheFile identifiers .
+    I.joinI . filterTracks [trackNo] .  I.joinI . e $ I.last
+    where
+        e = I.joinI . enumSummaries . I.mapChunks (catMaybes . map toSLD)
+        toSLD :: ZoomSummary -> Maybe [Summary (PCM Double)]
+        toSLD (ZoomSummary s) = toSummaryListPCMDouble s
+
+enumSummaryListPCMDouble :: (Functor m, MonadIO m)
+                         => Int
+                         -> I.Enumeratee [Stream] [[Summary (PCM Double)]] m a
+enumSummaryListPCMDouble level =
+    I.joinI . enumSummaryLevel level .
+    I.mapChunks (catMaybes . map toSLD)
+    where
+        toSLD :: ZoomSummary -> Maybe [Summary (PCM Double)]
+        toSLD (ZoomSummary s) = toSummaryListPCMDouble s
diff --git a/zoom-cache-pcm.cabal b/zoom-cache-pcm.cabal
--- a/zoom-cache-pcm.cabal
+++ b/zoom-cache-pcm.cabal
@@ -3,7 +3,7 @@
 -- The package version. See the Haskell package versioning policy
 -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
 -- standards guiding when and how versions should be incremented.
-Version:             0.2.1.0
+Version:             0.2.2.0
 
 Synopsis:            Library for zoom-cache PCM audio codecs
 
@@ -48,10 +48,13 @@
     containers                >= 0.2     && < 0.5,
     iteratee                  >= 0.8.6.0 && < 0.9,
     ListLike                  >= 1.0     && < 4,
-    zoom-cache                >= 0.7.0.0 && < 0.10
+    mtl                       >= 2.0.0.0 && < 3,
+    type-level,
+    zoom-cache                >= 0.9.0.0 && < 0.10
 
   Exposed-modules:
     Data.ZoomCache.PCM
+    Data.ZoomCache.PCM.Enumeratee
     Data.ZoomCache.PCM.IEEE754
     Data.ZoomCache.PCM.Int
     Data.ZoomCache.PCM.Internal
