diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) Matt Morrow.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. 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.
+3. The names of the author may not be used to endorse or promote
+   products derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+> import Distribution.Simple
+> main :: IO ()
+> main = defaultMain
+
diff --git a/pure-fft.cabal b/pure-fft.cabal
new file mode 100644
--- /dev/null
+++ b/pure-fft.cabal
@@ -0,0 +1,21 @@
+name:               pure-fft
+version:            0.1.0
+cabal-version:      >= 1.2
+build-type:         Simple
+license:            BSD3
+license-file:       LICENSE
+category:           Numeric, Math
+author:             Matt Morrow
+copyright:          Matt Morrow
+maintainer:         Matt Morrow <mjm2002@gmail.com>
+stability:          experimental
+synopsis:           Fast Fourier Transform
+description:        A pure-haskell implementation
+                    of the radix-2 DIT version of
+                    the Cooley-Tukey FFT algorithm.
+
+library
+  build-depends:    base
+  ghc-options:      -O2
+  hs-source-dirs:   src
+  exposed-modules:  Numeric.FFT
diff --git a/src/Numeric/FFT.hs b/src/Numeric/FFT.hs
new file mode 100644
--- /dev/null
+++ b/src/Numeric/FFT.hs
@@ -0,0 +1,115 @@
+{-# OPTIONS_GHC -O2 #-}
+
+{- |
+  Module      :  Numeric.FFT
+  Copyright   :  (c) Matt Morrow 2008
+  License     :  BSD3
+  Maintainer  :  Matt Morrow <mjm2002@gmail.com>
+  Stability   :  experimental
+  Portability :  portable
+
+
+  A radix-2 DIT version of
+  the Cooley-Tukey FFT algorithm.
+-}
+
+module Numeric.FFT (
+    fft, ifft
+  , dft, idft
+) where
+
+import Data.List(foldl')
+import Data.Complex(Complex(..))
+
+-----------------------------------------------------------------------------
+
+-- | /O(n lg n)/. A radix-2 DIT
+--  (decimation-in-time) version of the
+--  Cooley-Tukey FFT algorithm.
+--  The length of the input list /must/
+--  be a power of two, or only the prefix
+--  of the list of length equal to the largest
+--  power of two less than the length of the list
+--  will be transformed.
+fft :: [Complex Double] -> [Complex Double]
+fft []    = []
+fft [x,y] = dft [x,y]
+fft xs    = fmap (go len ys zs) [0..len*2-1]
+  where (ys,zs) = (fft***fft)
+            . deinterleave $ xs
+        len = length ys
+        go len xs ys k
+          | k <  len  = (xs!!k) + (ys!!k) * f k (len*2)
+          | otherwise = let k' = k - len
+              in (xs!!k') - (ys!!k') * f k' (len*2)
+          where i = 0 :+ 1
+                fi = fromIntegral
+                f k n = exp (negate(2*pi*i*fi k)/fi n)
+        (***) f g (x,y) = (f x, g y)
+        deinterleave :: [a] -> ([a],[a])
+        deinterleave = unzip . pairs
+        pairs :: [a] -> [(a,a)]
+        pairs []       = []
+        pairs (x:y:zs) = (x,y) : pairs zs
+        pairs _        = []
+
+
+ifft :: [Complex Double] -> [Complex Double]
+ifft xs = let n = (fromIntegral . length) xs in fmap (/n) (fft xs)
+
+-----------------------------------------------------------------------------
+
+-- | /O(n^2)/. The Discrete Fourier Transform.
+dft :: [Complex Double] -> [Complex Double]
+dft xs = let len = length xs
+          in zipWith (go len) [0..len-1] (repeat xs)
+  where i = 0 :+ 1
+        fi = fromIntegral
+        go len k xs = foldl' (+) 0 . flip fmap [0..len-1]
+          $ \n -> (xs!!n) * exp (negate(2*pi*i*fi n*fi k)/fi len)
+
+idft :: [Complex Double] -> [Complex Double]
+idft xs = let n = (fromIntegral . length) xs in fmap (/n) (dft xs)
+
+-----------------------------------------------------------------------------
+
+{-
+"A radix-2 decimation-in-time (DIT) FFT is
+the simplest and most common form of the
+Cooley-Tukey algorithm, although highly
+optimized Cooley-Tukey implementations
+typically use other forms of the algorithm"
+
+"Radix-2 DIT divides a DFT of size N into
+two interleaved DFTs (hence the name "radix-2")
+of size N/2 with each recursive stage."
+
+<http://en.wikipedia.org/wiki/Cooley-Tukey_FFT_algorithm>
+-}
+
+-----------------------------------------------------------------------------
+
+{-
+[m@ganon SPHODRA]$ time ./test_fft
+(-32767.999999213338) :+ (-6.835652750528328e8)
+
+real    0m0.757s
+user    0m0.729s
+sys     0m0.019s
+
+
+[m@ganon SPHODRA]$ time ./test_dft
+^C
+
+real    0m21.221s
+user    0m20.938s
+sys     0m0.017s
+
+import Math.FFT(fft)
+main = print . last . fft . fmap fromIntegral $ [0..2^16-1]
+
+import Math.FFT(dft)
+main = print . last . dft . fmap fromIntegral $ [0..2^16-1]
+-}
+
+-----------------------------------------------------------------------------
