diff --git a/sox.cabal b/sox.cabal
--- a/sox.cabal
+++ b/sox.cabal
@@ -1,5 +1,5 @@
 Name:             sox
-Version:          0.2.0.2
+Version:          0.2.1
 License:          GPL
 License-File:     LICENSE
 Author:           Henning Thielemann <haskell@henning-thielemann.de>
@@ -23,7 +23,7 @@
    There is some ancient code,
    which allows interactive playback using the shell-pipe package on GHC-6.2,
    where no runInteractiveProcess was available.
-Tested-With:       GHC==6.8.2, GHC==6.10.4, GHC==6.12.1
+Tested-With:       GHC==6.8.2, GHC==6.10.4, GHC==6.12.1, GHC==7.0.4, GHC==7.2.1
 Cabal-Version:     >=1.2
 Build-Type:        Simple
 Extra-Source-Files:
@@ -49,9 +49,9 @@
     transformers >=0.2 && <0.3
   If flag(splitBase)
     Build-Depends:
-      base >= 2 && <5,
-      process >= 1.0 && < 1.1,
-      containers >= 0.1 && <0.4
+      process >= 1.0 && < 1.2,
+      containers >= 0.1 && <0.5,
+      base >= 2 && <5
   Else
     Build-Depends:
       special-functors >= 1.0 && <1.1,
@@ -62,7 +62,7 @@
     Hs-Source-Dirs: windows/src
   Else
     Hs-Source-Dirs: unix/src
-    Build-Depends: unix >=2.3 && <2.5
+    Build-Depends: unix >=2.3 && <2.6
 
   GHC-Options: -Wall
 
diff --git a/src/Sound/Sox/Signal/List.hs b/src/Sound/Sox/Signal/List.hs
--- a/src/Sound/Sox/Signal/List.hs
+++ b/src/Sound/Sox/Signal/List.hs
@@ -21,7 +21,7 @@
 
 import Foreign.Storable (Storable (..), )
 
-import Foreign (Ptr, alloca, sizeOf, poke, peek, )
+import Foreign (Ptr, alloca, )
 import System.IO (withBinaryFile, IOMode(WriteMode,ReadMode), Handle, hPutBuf, hGetBuf, )
 import Control.Exception.Extensible (SomeException, try, )
 import Control.Monad (liftM)
diff --git a/src/Sound/Sox/Write.hs b/src/Sound/Sox/Write.hs
--- a/src/Sound/Sox/Write.hs
+++ b/src/Sound/Sox/Write.hs
@@ -1,4 +1,4 @@
-module Sound.Sox.Write where
+module Sound.Sox.Write (simple, extended, manyExtended, ) where
 
 import qualified Sound.Sox.Frame as Frame
 import Sound.Sox.System (catchCtrlC, )
@@ -8,6 +8,9 @@
 import qualified Sound.Sox.Private.Arguments as Args
 import Data.Monoid (mconcat, )
 
+import qualified Data.Traversable as Trav
+import qualified Data.Foldable as Fold
+
 import qualified System.Process as Proc
 import qualified System.IO as IO
 import Control.Exception (bracket, )
@@ -53,28 +56,81 @@
       {- ^ sample rate -} ->
    sig y ->
    IO ExitCode
-extended write srcOpts dstOpts fileName sampleRate stream =
+extended write srcOpts dstOpts fileName sampleRate signal =
    bracket
-      (Proc.runInteractiveProcess "sox"
-          (Args.decons $ mconcat $
-           OptPriv.toArguments
-             (mconcat $
-              srcOpts :
-              Option.numberOfChannels
-                 (Frame.withSignal Frame.numberOfChannels stream) :
-              Option.sampleRate sampleRate :
-              Option.format (Frame.withSignal Frame.format stream) :
-              []) :
-           Args.pipe :
-           OptPriv.toArguments dstOpts :
-           Args.fileName fileName :
-           [])
-          Nothing Nothing)
-      (\(input,output,err,_proc) ->
-          mapM_ IO.hClose [input, output, err])
+      (open srcOpts dstOpts fileName sampleRate signal)
+      close
       (\(input,_,_,proc) ->
          catchCtrlC >>
-         write input stream >>
+         write input signal >>
          return proc)
    -- get exit code, e.g. when options were wrong
    >>= Proc.waitForProcess
+
+{- |
+The traversable functor @f@ might be 'Maybe' or '[]'.
+It allows you to write to many files simultaneously
+and returns the exit codes of all writing processes.
+-}
+manyExtended ::
+   (Frame.C y, Trav.Traversable f) =>
+   (f IO.Handle -> sig y -> IO ())
+      {- ^ Writer routine -
+           e.g. 'Sound.Sox.Signal.List.put'
+           or 'Data.StorableVector.hPut' -} ->
+   Option.T
+      {- ^ source options, usually none -} ->
+   Option.T
+      {- ^ target options -} ->
+   f FilePath ->
+   Int
+      {- ^ sample rate -} ->
+   sig y ->
+   IO (f ExitCode)
+manyExtended write srcOpts dstOpts fileNames sampleRate signal =
+   bracket
+      (Trav.traverse
+         (\fileName -> open srcOpts dstOpts fileName sampleRate signal)
+         fileNames)
+      (Fold.traverse_ close)
+      (\handles ->
+         catchCtrlC >>
+         write (fmap (\(input,_,_,_) -> input) handles) signal >>
+         return (fmap (\(_,_,_,proc) -> proc) handles))
+   -- get exit code, e.g. when options were wrong
+   >>= Trav.traverse Proc.waitForProcess
+
+
+type Handle = (IO.Handle, IO.Handle, IO.Handle, Proc.ProcessHandle)
+
+open ::
+   (Frame.C y) =>
+   Option.T
+      {- ^ source options, usually none -} ->
+   Option.T
+      {- ^ target options -} ->
+   FilePath ->
+   Int
+      {- ^ sample rate -} ->
+   sig y ->
+   IO Handle
+open srcOpts dstOpts fileName sampleRate signal =
+   Proc.runInteractiveProcess "sox"
+      (Args.decons $ mconcat $
+       OptPriv.toArguments
+         (mconcat $
+          srcOpts :
+          Option.numberOfChannels
+             (Frame.withSignal Frame.numberOfChannels signal) :
+          Option.sampleRate sampleRate :
+          Option.format (Frame.withSignal Frame.format signal) :
+          []) :
+       Args.pipe :
+       OptPriv.toArguments dstOpts :
+       Args.fileName fileName :
+       [])
+      Nothing Nothing
+
+close :: Handle -> IO ()
+close (input,output,err,_proc) =
+   mapM_ IO.hClose [input, output, err]
