diff --git a/Sound/Analysis/Meapsoft.hs b/Sound/Analysis/Meapsoft.hs
--- a/Sound/Analysis/Meapsoft.hs
+++ b/Sound/Analysis/Meapsoft.hs
@@ -19,68 +19,69 @@
 import Sound.Analysis.Meapsoft.Header
 
 -- | Data type representing a MEAPsoft anaylsis file.
-data MEAP = MEAP { -- | The list of 'Feature's contained in the
-                   --   analysis file.
-                   features :: [Feature]
-                   -- | The number of frames (rows) contained in the
-                   --   analysis file.
-                 , n_frames :: Int
-                   -- | The analysis data stored in a 'UArray'.
-                   --   Indices are of the form (row, column).
-                 , uarray_data :: UArray (Int, Int) Double }
+data MEAP t = MEAP { -- | The list of 'Feature's contained in the
+                     --   analysis file.
+                     features :: [Feature]
+                     -- | The number of frames (rows) contained in the
+                     --   analysis file.
+                   , n_frames :: Int
+                     -- | The analysis data stored in a 'UArray'.
+                     --   Indices are of the form (row, column).
+                   , uarray_data :: UArray (Int, Int) t }
 
 -- | Load a MEAPsoft analysis file, either a segmentation file or a
 --   feature file.
 --
 -- > Right m <- read_meap "/home/rohan/data/audio/jonchaies.wav.seg"
 -- > map feature_name (features m) == ["onset_time","chunk_length"]
-read_meap :: FilePath -> IO (Either String MEAP)
+read_meap :: Meap_Data t => FilePath -> IO (Either String (MEAP t))
 read_meap fn = do
   r <- read_header fn
   case r of
     (Left e) -> return (Left e)
     (Right h) -> do let nc = sum (map feature_degree h)
                     (nf, d) <- read_data fn nc
-                    return (Right (MEAP h nf d))
+                    let ua = meap_data_uarray nc nf d
+                    return (Right (MEAP h nf ua))
 
 -- | The number of columns at each analysis frame (row).  Segmentation
 -- files have two columns, onset time and segment length.
 --
 -- > n_columns m == 2
-n_columns :: MEAP -> Int
+n_columns :: MEAP t -> Int
 n_columns = sum . map feature_degree . features
 
 -- | Extract the indicated column as a list.  The length of the column
 -- is the 'n_frames' of the analysis file.
 --
 -- > length (column_l m 0) == n_frames m
-column_l :: MEAP -> Int -> [Double]
+column_l :: Meap_Data t => MEAP t -> Int -> [t]
 column_l m j =
     let d = uarray_data m
         is = [0 .. n_frames m - 1]
-    in map (\i -> d ! (i, j)) is
+    in map (\i -> d `meap_data_index` (i, j)) is
 
 -- | Extract the indicated frame (row) as a list.
 --
 -- > length (frame_l m 0) == n_columns m
-frame_l :: MEAP -> Int -> [Double]
+frame_l :: Meap_Data t => MEAP t -> Int -> [t]
 frame_l m i =
     let d = uarray_data m
         js = [0 .. n_columns m - 1]
-    in map (\j -> d ! (i, j)) js
+    in map (\j -> d `meap_data_index` (i, j)) js
 
 -- | Extract data from the indicated frame and column.
 --
 -- > position m (0,0) == frame_l m 0 !! 0
-position :: MEAP -> (Int, Int) -> Double
-position m (i, j) = uarray_data m ! (i, j)
+position :: Meap_Data t => MEAP t -> (Int, Int) -> t
+position m (i, j) = uarray_data m `meap_data_index` (i, j)
 
 -- | Extract segmentation data as a list.  The segmentation data is
 --   given by the two columns onset_time and chunk_length.
 --
 -- > length (segments_l m) == n_frames m
 -- > segments_l m !! 0 == (\[i,j] -> (i,j)) (frame_l m 0)
-segments_l :: MEAP -> [(Double, Double)]
+segments_l :: Meap_Data t => MEAP t -> [(t,t)]
 segments_l m =
     let fs = features m
         ec n = feature_column (required_feature n fs)
diff --git a/Sound/Analysis/Meapsoft/Data.hs b/Sound/Analysis/Meapsoft/Data.hs
--- a/Sound/Analysis/Meapsoft/Data.hs
+++ b/Sound/Analysis/Meapsoft/Data.hs
@@ -1,31 +1,42 @@
 -- | Meapsoft analysis data input.
-module Sound.Analysis.Meapsoft.Data ( read_data ) where
+module Sound.Analysis.Meapsoft.Data where
 
-import Data.Array.Unboxed
+import Data.Array.Unboxed {- array -}
 import qualified Data.ByteString as B {- bytestring -}
-import qualified Data.ByteString.Char8 as C
-import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Char8 as C {- bytestring -}
+import qualified Data.ByteString.Lazy as L {- bytestring -}
 import qualified Data.ByteString.Lex.Double as P {- bytestring-lexing -}
 import qualified Text.Delimited as D {- delimited-text -}
 
-read_inf :: String -> Double
+read_inf :: Fractional n => String -> n
 read_inf s =
     case s of
       "Infinity"  ->  1/0
       "-Infinity" -> -1/0
       _ -> error ("read_inf: could not read " ++ show s)
 
-to_f :: B.ByteString -> Double
-to_f s = maybe (read_inf (C.unpack s)) fst (P.readDouble s)
+to_f :: Fractional n => B.ByteString -> n
+to_f s = maybe (read_inf (C.unpack s)) (realToFrac . fst) (P.readDouble s)
 
 -- | Given the number of columns, reads an entire MEAPsoft data set
---   into an 'UArray' and returns the data paired with the number of
---   rows.
-read_data :: FilePath -> Int -> IO (Int, UArray (Int, Int) Double)
+--   into a list and returns the data paired with the number of rows.
+read_data :: Fractional n => FilePath -> Int -> IO (Int,[n])
 read_data fn nc = do
   s <- L.readFile fn
   let (Right xs) = D.decode " \t" s
       xs' = map (take nc . drop 1) (drop 1 xs)
       nr = length xs'
       ds = map to_f (concat xs')
-  return (nr, listArray ((0,0), (nr - 1, nc - 1)) ds)
+  return (nr,ds)
+
+class Floating a => Meap_Data a where
+    meap_data_uarray :: Int -> Int -> [a] -> UArray (Int,Int) a
+    meap_data_index :: UArray (Int,Int) a -> (Int,Int) -> a
+
+instance Meap_Data Float where
+    meap_data_uarray nc nr ds = listArray ((0,0),(nr - 1,nc - 1)) ds
+    meap_data_index = (!)
+
+instance Meap_Data Double where
+    meap_data_uarray nc nr ds = listArray ((0,0),(nr - 1,nc - 1)) ds
+    meap_data_index = (!)
diff --git a/Sound/Analysis/Meapsoft/Measure.hs b/Sound/Analysis/Meapsoft/Measure.hs
--- a/Sound/Analysis/Meapsoft/Measure.hs
+++ b/Sound/Analysis/Meapsoft/Measure.hs
@@ -2,13 +2,13 @@
 module Sound.Analysis.Meapsoft.Measure where
 
 -- | Cycles per second to MEL conversion, see Stevens & Volkman, 1940.
-cps_mel :: Double -> Double
+cps_mel :: Floating n => n -> n
 cps_mel f = 1127.01048 * log (f / 700 + 1)
 
 -- | MEL to cycles per second conversion, see Stevens & Volkman, 1940.
-mel_cps :: Double -> Double
+mel_cps :: Floating n => n -> n
 mel_cps m = 700 * (exp (m / 1127.01048) - 1)
 
 -- | Cycles per second to ERB conversion, see Glasberg & Moore, 1990, p. 114.
-cps_erb :: Double -> Double
+cps_erb ::  Floating n => n -> n
 cps_erb f = 21.4 * logBase 10 (0.00437 * f + 1)
diff --git a/hmeap.cabal b/hmeap.cabal
--- a/hmeap.cabal
+++ b/hmeap.cabal
@@ -1,11 +1,11 @@
 Name:              hmeap
-Version:           0.12
+Version:           0.14
 Synopsis:          Haskell Meapsoft Parser
 Description:       Parser for the analysis files produced by the
                    Meapsoft feature extractor.
 License:           GPL
 Category:          Sound
-Copyright:         Rohan Drape and others, 2007-2012
+Copyright:         Rohan Drape and others, 2007-2013
 Author:            Rohan Drape
 Maintainer:        rd@slavepianos.org
 Stability:         Experimental
