diff --git a/sample-frame.cabal b/sample-frame.cabal
--- a/sample-frame.cabal
+++ b/sample-frame.cabal
@@ -1,5 +1,5 @@
 Name:             sample-frame
-Version:          0.0.1
+Version:          0.0.2
 License:          BSD3
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -13,25 +13,29 @@
    to handle signed and unsigned samples
    of various size and number of channels in a uniform way.
    .
-   We expect that you use the types Int8, Word8 and so on
+   We expect that you use the types 'Int8', 'Word8' and so on
    for monophonic samples and thus provide instances of the class for them.
    Further we define Stereo record and mu-law sample type.
    Quadrophony can be achieved by nested Stereo value,
    but I'm uncertain, whether this is a good way to go.
    Maybe we add 5+1 channels or so in future.
    .
-   This is used by packages sox, alsa, synthesizer.
+   This is used by packages @sox@, @alsa@, @synthesizer@.
 Tested-With:       GHC==6.10.4
 Cabal-Version:     >=1.2
 Build-Type:        Simple
 
+Flag buildBenchmarks
+  description: Build benchmark executables
+  default:     False
+
 Flag splitBase
   description: Choose the new smaller, split-up base package.
 
 Library
   Build-Depends:
-    storable-record >=0.0.1 && <0.1,
-    QuickCheck >= 1.0 && <2.0
+    storable-record >=0.0.2 && <0.1,
+    QuickCheck >= 1.0 && <3.0
   If flag(splitBase)
     Build-Depends:
       base >= 2 && <5
@@ -48,3 +52,19 @@
     Sound.Frame
     Sound.Frame.Stereo
     Sound.Frame.MuLaw
+
+Executable speedtest
+  If flag(buildBenchmarks)
+    Build-Depends:
+      storablevector >=0.2.4 && <0.3,
+      storable-record >=0.0.2 && <0.1,
+      storable-tuple >=0.0.1 && <0.1
+  Else
+    Buildable: False
+  GHC-Options: -Wall -fexcess-precision -threaded
+-- -ddump-simpl-stats -ddump-asm
+  Hs-Source-Dirs: src
+  Main-Is: SpeedTest.hs
+  Other-Modules:
+    Sound.Frame.Stereo.Record
+    Sound.Frame.Stereo.Traversable
diff --git a/src/Sound/Frame.hs b/src/Sound/Frame.hs
--- a/src/Sound/Frame.hs
+++ b/src/Sound/Frame.hs
@@ -1,10 +1,24 @@
-module Sound.Frame where
+module Sound.Frame
+   (C(..),
+   numberOfChannelsFoldable,
+   sizeOfElementFoldable,
+   sizeOfElementType,
+   paddedSizeOf,
+   withSignal,
+   ) where
 
 import Data.Word (Word8, Word16, Word32, )
 import Data.Int (Int8, Int16, Int32, )
-import Foreign.Storable (sizeOf, )
+import Foreign.Storable (Storable, sizeOf, alignment, )
 
+import qualified Data.Foldable as Fold
 
+
+{- |
+This is a class for nested tuples used as sample frames.
+
+Should we make Storable a superclass of 'C'?
+-}
 class C y where
    {- | The argument is not touched and can be undefined -}
    numberOfChannels :: y -> Int
@@ -12,9 +26,41 @@
    Size of elements.
    In a nested record type, like @Stereo (Stereo a)@,
    it is the size of the atomic element, in our example @a@.
+   We assume that the atomic element values all have the same size,
+   such that @sizeOfElement undefined@ is defined.
    -}
    sizeOfElement :: y -> Int
 
+{- |
+Default implementations for a foldable Frame.
+-}
+numberOfChannelsFoldable ::
+   (C y, Fold.Foldable f) => f y -> Int
+numberOfChannelsFoldable =
+   Fold.foldl' (\n y -> n + numberOfChannels y) 0
+--   Fold.sum . fmap numberOfChannels
+
+sizeOfElementFoldable ::
+   (C y, Fold.Foldable f) => f y -> Int
+sizeOfElementFoldable =
+   sizeOfElement . head . Fold.toList
+
+{- |
+Returns the size of an undefined element.
+This might be more efficient than 'sizeOfElementFoldable'.
+-}
+sizeOfElementType ::
+   (C y) => f y -> Int
+sizeOfElementType =
+   sizeOfElement . elementType
+
+
+{-# INLINE elementType #-}
+elementType :: f a -> a
+elementType _ =
+   error "Sound.Frame.sizeOfElement may not depend on element values"
+
+
 instance C Word8 where
    numberOfChannels _ = 1
    sizeOfElement = sizeOf
@@ -48,5 +94,15 @@
    sizeOfElement = sizeOf
 
 
+{- |
+Space that an element consumes in a Storable Array.
+This is space for the element plus padding.
+-}
+-- cf. storable-record:FixedArray.roundUp
+paddedSizeOf :: Storable a => a -> Int
+paddedSizeOf x =
+   sizeOf x + mod (- sizeOf x) (alignment x)
+
+
 withSignal :: (y -> a) -> (sig y -> a)
-withSignal f _ = f undefined
+withSignal f _ = f (error "Frame: dummy signal parameter touched")
diff --git a/src/Sound/Frame/MuLaw.hs b/src/Sound/Frame/MuLaw.hs
--- a/src/Sound/Frame/MuLaw.hs
+++ b/src/Sound/Frame/MuLaw.hs
@@ -11,7 +11,7 @@
 import Data.Word (Word8, )
 import Data.Int (Int16, )
 
-import Test.QuickCheck (Arbitrary(arbitrary, coarbitrary), )
+import Test.QuickCheck (Arbitrary(arbitrary), )
 
 import Prelude hiding (map, )
 
@@ -27,7 +27,6 @@
 
 instance Arbitrary T where
    arbitrary = fmap (cons . fromIntegral :: Int -> T) arbitrary
-   coarbitrary = error "MuLaw.coarbitrary not implemented"
 
 
 {-# INLINE cons #-}
diff --git a/src/Sound/Frame/Stereo.hs b/src/Sound/Frame/Stereo.hs
--- a/src/Sound/Frame/Stereo.hs
+++ b/src/Sound/Frame/Stereo.hs
@@ -5,13 +5,16 @@
 
 import qualified Sound.Frame as Frame
 
-import Control.Applicative (liftA2, )
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+
+import Control.Applicative (Applicative, pure, (<*>), liftA2, )
 import Control.Monad (liftM2, )
 
-import Foreign.Storable.Record as Store
 import Foreign.Storable (Storable (..), )
+import Foreign.Ptr (Ptr, castPtr, )
 
-import Test.QuickCheck (Arbitrary(arbitrary, coarbitrary), )
+import Test.QuickCheck (Arbitrary(arbitrary), )
 
 import Prelude hiding (map, )
 
@@ -28,7 +31,6 @@
 
 instance (Arbitrary a) => Arbitrary (T a) where
    arbitrary = liftM2 cons arbitrary arbitrary
-   coarbitrary = error "Stereo.coarbitrary not implemented"
 
 
 {-# INLINE cons #-}
@@ -43,24 +45,44 @@
    {-# INLINE fmap #-}
    fmap = map
 
+-- useful for defining Additive instance
+instance Applicative T where
+   {-# INLINE pure #-}
+   pure a = Cons a a
+   {-# INLINE (<*>) #-}
+   Cons fl fr <*> Cons l r = Cons (fl l) (fr r)
 
-{-# INLINE store #-}
-store :: Storable a => Store.Dictionary (T a)
-store =
-   Store.run $
-   liftA2 Cons
-      (Store.element left)
-      (Store.element right)
+instance Fold.Foldable T where
+   {-# INLINE foldMap #-}
+   foldMap = Trav.foldMapDefault
 
+-- this allows for kinds of generic programming
+instance Trav.Traversable T where
+   {-# INLINE sequenceA #-}
+   sequenceA ~(Cons l r) = liftA2 Cons l r
+
+
+
+{-# INLINE castToElemPtr #-}
+castToElemPtr :: Ptr (T a) -> Ptr a
+castToElemPtr = castPtr
+
 instance (Storable a) => Storable (T a) where
    {-# INLINE sizeOf #-}
-   sizeOf = Store.sizeOf store
    {-# INLINE alignment #-}
-   alignment = Store.alignment store
    {-# INLINE peek #-}
-   peek = Store.peek store
    {-# INLINE poke #-}
-   poke = Store.poke store
+   -- cf. storable-record:FixedArray.roundUp
+   sizeOf ~(Cons l r) =
+      sizeOf l + mod (- sizeOf l) (alignment r) + sizeOf r
+   alignment ~(Cons l _) = alignment l
+   poke p (Cons l r) =
+      let q = castToElemPtr p
+      in  poke q l >> pokeElemOff q 1 r
+   peek p =
+      let q = castToElemPtr p
+      in  liftM2 Cons
+             (peek q) (peekElemOff q 1)
 
 
 instance Frame.C a => Frame.C (T a) where
diff --git a/src/Sound/Frame/Stereo/Record.hs b/src/Sound/Frame/Stereo/Record.hs
new file mode 100644
--- /dev/null
+++ b/src/Sound/Frame/Stereo/Record.hs
@@ -0,0 +1,88 @@
+{-
+This data type can be used as sample type for stereo signals.
+-}
+module Sound.Frame.Stereo.Record (T, left, right, cons, map, ) where
+
+import qualified Sound.Frame as Frame
+
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+
+import Control.Applicative (Applicative, pure, (<*>), liftA2, )
+import Control.Monad (liftM2, )
+
+import Foreign.Storable.Record as Store
+import Foreign.Storable (Storable (..), )
+
+import Test.QuickCheck (Arbitrary(arbitrary), )
+
+import Prelude hiding (map, )
+
+
+data T a = Cons {left, right :: !a}
+   deriving (Eq)
+
+
+instance Show a => Show (T a) where
+   showsPrec p x =
+      showParen (p >= 10)
+         (showString "Stereo.cons " . showsPrec 11 (left x) .
+          showString " " . showsPrec 11 (right x))
+
+instance (Arbitrary a) => Arbitrary (T a) where
+   arbitrary = liftM2 cons arbitrary arbitrary
+
+
+{-# INLINE cons #-}
+cons :: a -> a -> T a
+cons = Cons
+
+{-# INLINE map #-}
+map :: (a -> b) -> T a -> T b
+map f (Cons l r) = Cons (f l) (f r)
+
+instance Functor T where
+   {-# INLINE fmap #-}
+   fmap = map
+
+-- useful for defining Additive instance
+instance Applicative T where
+   {-# INLINE pure #-}
+   pure a = Cons a a
+   {-# INLINE (<*>) #-}
+   Cons fl fr <*> Cons l r = Cons (fl l) (fr r)
+
+instance Fold.Foldable T where
+   {-# INLINE foldMap #-}
+   foldMap = Trav.foldMapDefault
+
+-- this allows for kinds of generic programming
+instance Trav.Traversable T where
+   {-# INLINE sequenceA #-}
+   sequenceA ~(Cons l r) = liftA2 Cons l r
+
+
+{-# INLINE store #-}
+store :: Storable a => Store.Dictionary (T a)
+store =
+   Store.run $
+   liftA2 Cons
+      (Store.element left)
+      (Store.element right)
+
+instance (Storable a) => Storable (T a) where
+   {-# INLINE sizeOf #-}
+   sizeOf = Store.sizeOf store
+   {-# INLINE alignment #-}
+   alignment = Store.alignment store
+   {-# INLINE peek #-}
+   peek = Store.peek store
+   {-# INLINE poke #-}
+   poke = Store.poke store
+
+
+instance Frame.C a => Frame.C (T a) where
+   {-# INLINE numberOfChannels #-}
+   numberOfChannels y = 2 * Frame.numberOfChannels (left y)
+   {-# INLINE sizeOfElement #-}
+   sizeOfElement = Frame.sizeOfElement . left
diff --git a/src/Sound/Frame/Stereo/Traversable.hs b/src/Sound/Frame/Stereo/Traversable.hs
new file mode 100644
--- /dev/null
+++ b/src/Sound/Frame/Stereo/Traversable.hs
@@ -0,0 +1,80 @@
+{-
+This data type can be used as sample type for stereo signals.
+-}
+module Sound.Frame.Stereo.Traversable (T, left, right, cons, map, ) where
+
+import qualified Sound.Frame as Frame
+
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+
+import Control.Applicative (Applicative, pure, (<*>), liftA2, )
+import Control.Monad (liftM2, )
+
+import Foreign.Storable.Traversable as Store
+import Foreign.Storable (Storable (..), )
+
+import Test.QuickCheck (Arbitrary(arbitrary), )
+
+import Prelude hiding (map, )
+
+
+data T a = Cons {left, right :: !a}
+   deriving (Eq)
+
+
+instance Show a => Show (T a) where
+   showsPrec p x =
+      showParen (p >= 10)
+         (showString "Stereo.cons " . showsPrec 11 (left x) .
+          showString " " . showsPrec 11 (right x))
+
+instance (Arbitrary a) => Arbitrary (T a) where
+   arbitrary = liftM2 cons arbitrary arbitrary
+
+
+{-# INLINE cons #-}
+cons :: a -> a -> T a
+cons = Cons
+
+{-# INLINE map #-}
+map :: (a -> b) -> T a -> T b
+map f ~(Cons l r) = Cons (f l) (f r)
+
+instance Functor T where
+   {-# INLINE fmap #-}
+   fmap = map
+
+-- useful for defining Additive instance
+instance Applicative T where
+   {-# INLINE pure #-}
+   pure a = Cons a a
+   {-# INLINE (<*>) #-}
+   ~(Cons fl fr) <*> ~(Cons l r) = Cons (fl l) (fr r)
+
+instance Fold.Foldable T where
+   {-# INLINE foldMap #-}
+   foldMap = Trav.foldMapDefault
+
+-- this allows for kinds of generic programming
+instance Trav.Traversable T where
+   {-# INLINE sequenceA #-}
+   sequenceA ~(Cons l r) = liftA2 Cons l r
+
+
+instance (Storable a) => Storable (T a) where
+   {-# INLINE sizeOf #-}
+   sizeOf = Store.sizeOf
+   {-# INLINE alignment #-}
+   alignment = Store.alignment
+   {-# INLINE peek #-}
+   peek = Store.peek (error "instance Traversable Stereo is lazy, so we do not provide a real value here")
+   {-# INLINE poke #-}
+   poke = Store.poke
+
+
+instance Frame.C a => Frame.C (T a) where
+   {-# INLINE numberOfChannels #-}
+   numberOfChannels = Frame.numberOfChannelsFoldable
+   {-# INLINE sizeOfElement #-}
+   sizeOfElement = Frame.sizeOfElementType
diff --git a/src/SpeedTest.hs b/src/SpeedTest.hs
new file mode 100644
--- /dev/null
+++ b/src/SpeedTest.hs
@@ -0,0 +1,101 @@
+{-# OPTIONS_GHC -funbox-strict-fields -ddump-simpl -ddump-simpl-stats -O #-}
+{-  -dverbose-core2core -ddump-simpl-iterations -}
+{-
+This module allows to compare speed of custom Storable instance of Stereo
+versus the ones implemented using Storable.Record and Storable.Traversable.
+-}
+module Main where
+
+-- import qualified Sound.Frame.Stereo as Stereo
+import qualified Sound.Frame.Stereo.Traversable as Stereo
+-- import qualified Sound.Frame.Stereo.Record as Stereo
+import qualified Data.StorableVector as SV
+
+import Control.Applicative (pure, liftA2, )
+
+import Foreign.Storable.Tuple ()
+
+import Data.Int (Int16)
+
+import GHC.Float (float2Int, )
+
+
+{-
+GHC-6.10.4:
+
+Custom Storable instance:
+real    0m0.680s
+user    0m0.560s
+sys     0m0.112s
+
+Storable.Traversable instance:
+real    0m25.187s
+user    0m25.014s
+sys     0m0.152s
+
+Storable.Record instance:
+real    0m3.017s
+user    0m2.844s
+sys     0m0.168s
+-}
+stereo :: SV.Vector (Stereo.T Int16)
+stereo =
+   fst $ SV.unfoldrN 10000000
+      (\x0 ->
+          let frac x = x - fromIntegral (float2Int x)
+              x1 = frac (x0+440/44100)
+              y0 = 2*x0-1
+              toInt16 y =
+                 fromIntegral $
+                 float2Int (y*fromIntegral(maxBound::Int16))
+          in  Just (Stereo.cons (toInt16 y0) (toInt16 y0), x1))
+      (0::Float)
+
+{-
+GHC-6.10.4:
+
+Custom Storable instance:
+real    0m0.698s
+user    0m0.668s
+sys     0m0.032s
+
+Storable.Traversable instance:
+real    0m47.012s
+user    0m46.839s
+sys     0m0.164s
+
+Storable.Record instance:
+real    0m4.382s
+user    0m4.336s
+sys     0m0.044s
+
+
+GHC-6.12.1:
+
+Storable.Traversable instance:
+real    0m47.021s
+user    0m46.827s
+sys     0m0.108s
+-}
+stereoSum :: SV.Vector (Stereo.T Int16) -> Stereo.T Int16
+stereoSum =
+   SV.foldl' (liftA2 (+)) (pure 0)
+
+stereoPair :: SV.Vector (Int16,Int16)
+stereoPair =
+   fst $ SV.unfoldrN 10000000
+      (\x0 ->
+          let frac x = x - fromIntegral (float2Int x)
+              x1 = frac (x0+440/44100)
+              y0 = 2*x0-1
+              toInt16 y =
+                 fromIntegral $
+                 float2Int (y*fromIntegral(maxBound::Int16))
+          in  Just ((toInt16 y0, toInt16 y0), x1))
+      (0::Float)
+
+
+main :: IO ()
+main =
+   print $ stereoSum stereo
+--   SV.writeFile "speed.s16" stereo
