diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for lambdasound
 
+## 1.0.1 -- 2023-10-13
+
+* Add `withSampledSound` and `withSampledSoundPulse`
+* Fix incorrect memoization for sequential and parallel sounds
+
 ## 1.0.0 -- 2023-10-12
 
 * First version. Released on an unsuspecting world.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -52,8 +52,13 @@
   play sampleRate volume ascending
 ```
 
-You can also take a look at `example/Example1.hs` and `example/Example2.hs` for bigger examples and play them with `cabal run example1` and `cabal run example2`.
+You can also take a look at `example/Example1.hs` and `example/Example2.hs` for bigger examples and play them with:
 
+```haskell
+cabal run example1
+cabal run example2
+```
+
 ## Feature Overview
 
 - Play sounds with SDL2
@@ -72,7 +77,7 @@
 
 ## Building
 
-`lambdasound` can be built as usual with the `cabal` package manager. For playing sounds, you will need to have **SDL2** installed.
+`lambdasound` can be built as usual with the `cabal` package manager. 
 
 ```
 git clone https://github.com/Simre1/lambdasound
@@ -80,9 +85,14 @@
 ```
 
 You can run the example with:
-```
-cabal run example
+
+```haskell
+cabal run example1
+cabal run example2
 ```
+
+For this library, you will need to have **SDL2** installed. Take a look at [proteeaudio-sdl](https://hackage.haskell.org/package/proteaaudio-sdl) for installation instructions.
+
 
 ## Contributing
 
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -3,6 +3,7 @@
 import Data.Coerce
 import LambdaSound
 import Test.Tasty.Bench
+import qualified Data.Massiv.Array as M
 
 main :: IO ()
 main =
@@ -21,7 +22,9 @@
           bench "Cached sound" $ nfSound cachedSound,
           bench "Timed parallel sound" $ nfSound timedParallelSound,
           bench "Unfold pulse" $ nfSound unfoldPulse,
-          bench "Unfold normally" $ nfSound unfoldNormally
+          bench "Unfold normally" $ nfSound unfoldNormally,
+          bench "With sampled sound" $ nfSound useSampledSound,
+          bench "Repeated with sampled sound" $ nfSound repeatedSampledSound
         ]
     ]
 
@@ -73,17 +76,27 @@
 
 timedParallelSound :: Sound T Pulse
 timedParallelSound =
-  parallel $ mconcat $
-    replicate 5 [ 0.5 |-> simplePulse,
-      1 |-> simplePulse,
-      1.5 |-> simplePulse,
-      0.7 |-> simplePulse,
-      2 |-> simplePulse,
-      1.5 |-> simplePulse
-    ]
+  parallel $
+    mconcat $
+      replicate
+        5
+        [ 0.5 |-> simplePulse,
+          1 |-> simplePulse,
+          1.5 |-> simplePulse,
+          0.7 |-> simplePulse,
+          2 |-> simplePulse,
+          1.5 |-> simplePulse
+        ]
 
 unfoldPulse :: Sound T Pulse
 unfoldPulse = 5 |-> unfoldlSoundPulse (\s -> (s, succ s)) 0
 
 unfoldNormally :: Sound T Pulse
 unfoldNormally = 5 |-> unfoldlSound (\s -> (s, succ s)) 0
+
+useSampledSound :: Sound T Pulse
+useSampledSound = setDuration 5 $ withSampledSoundPulse simplePulse $ \samples ->
+  makeSound $ \_ index -> samples M.! (index `mod` M.unSz (M.size samples))
+
+repeatedSampledSound :: Sound T Pulse
+repeatedSampledSound = repeatSound 20 useSampledSound
diff --git a/example/Example1.hs b/example/Example1.hs
--- a/example/Example1.hs
+++ b/example/Example1.hs
@@ -2,60 +2,75 @@
 import LambdaSound
 
 main :: IO ()
-main = play 44100 0.4 $ simpleReverb 0.1 $ applyIIRFilter (highPassFilter 600 1) sound
+main = play 44100 0.4 $
+    let downwards = sequentially $ setDuration 0.25 . note
+          <$> [g4, f4, e4, d4, f4, e4, d4, c4, e4, d4, c4, b3]
+     in sequentially
+          [ downwards,
+            dropSound 0.25 (reverseSound $ dropSound 0.5 downwards),
+            setDuration 0.25 (parallel $ note <$> [c4, e4]),
+            setDuration 0.25 (parallel $ note <$> [c4, e4, g4]),
+            setDuration 0.5 (parallel $ note <$> [c4, g4, c5])
+          ]
 
-sound :: Sound T Pulse
-sound = melody <> background
+-- Design a note sample
+note :: Semitone -> Sound I Pulse
+note st = easeInOut 2 $ asNote sawWave st + asNote (harmonic triangleWave) st
 
-background :: Sound T Pulse
-background =
-  repeatSound 3 $
-    sequentially $
-      fmap
-        (setDuration 0.5)
-        [ note c3,
-          parallel $ note <$> [e3, g3],
-          parallel $ note <$> [e3, g3],
-          parallel $ note <$> [e3, g3]
-        ]
+-- -- simpleReverb 0.1 $ applyIIRFilter (highPassFilter 600 1) sound
 
-melody :: Sound T Pulse
-melody =
-  let mel =
-        repeatSound
-          3
-          ( sequentially $
-              fmap
-                (setDuration 0.5)
-                [ note c4,
-                  note e4,
-                  note g4,
-                  note e4
-                ]
-          )
-          >>> end
-      end = setDuration 2 $ parallel [note c4, note c3, note g3]
-   in mel
+-- sound :: Sound T Pulse
+-- sound = melody <> background
 
-note :: Semitone -> Sound T Pulse
-note st =
-  applyEnvelope (Envelope 0.2 0.1 0.2 0.8) $
-    setDuration 1 $
-      asNote (harmonic sineWave) st
+-- background :: Sound T Pulse
+-- background =
+--   repeatSound 3 $
+--     sequentially $
+--       fmap
+--         (setDuration 0.5)
+--         [ note c3,
+--           parallel $ note <$> [e3, g3],
+--           parallel $ note <$> [e3, g3],
+--           parallel $ note <$> [e3, g3]
+--         ]
 
--- Further examples
+-- melody :: Sound T Pulse
+-- melody =
+--   let mel =
+--         repeatSound
+--           3
+--           ( sequentially $
+--               fmap
+--                 (setDuration 0.5)
+--                 [ note c4,
+--                   note e4,
+--                   note g4,
+--                   note e4
+--                 ]
+--           )
+--           >>> end
+--       end = setDuration 2 $ parallel [note c4, note c3, note g3]
+--    in mel
 
-metronome :: Sound T Pulse
-metronome = repeatSound 10 $ setDuration 1 $ note c4 >>> setDuration 2 silence
+-- note :: Semitone -> Sound T Pulse
+-- note st =
+--   applyEnvelope (Envelope 0.2 0.1 0.2 0.8) $
+--     setDuration 1 $
+--       asNote (harmonic sineWave) st
 
-upSound :: Sound T Pulse
-upSound =
-  zipSoundWith (*) ((\p -> 1 - coerce p) <$> progress) $
-    speedUp $
-      upwards >>> takeSound 2 (raiseSemitones 12 upwards) >>> setDuration 1 (note g5)
+-- -- Further examples
 
-upwards :: Sound T Pulse
-upwards = setDuration 3.5 $ sequentially $ note <$> [c4, d4, e4, f4, g4, a4, b4]
+-- metronome :: Sound T Pulse
+-- metronome = repeatSound 10 $ setDuration 1 $ note c4 >>> setDuration 2 silence
 
-speedUp :: Sound T Pulse -> Sound T Pulse
-speedUp = changeTempo $ \p -> p ** 2
+-- upSound :: Sound T Pulse
+-- upSound =
+--   zipSoundWith (*) ((\p -> 1 - coerce p) <$> progress) $
+--     speedUp $
+--       upwards >>> takeSound 2 (raiseSemitones 12 upwards) >>> setDuration 1 (note g5)
+
+-- upwards :: Sound T Pulse
+-- upwards = setDuration 3.5 $ sequentially $ note <$> [c4, d4, e4, f4, g4, a4, b4]
+
+-- speedUp :: Sound T Pulse -> Sound T Pulse
+-- speedUp = changeTempo $ \p -> p ** 2
diff --git a/lambdasound.cabal b/lambdasound.cabal
--- a/lambdasound.cabal
+++ b/lambdasound.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               lambdasound
-version:            1.0.0
+version:            1.0.1
 synopsis:           A libary for generating low-level sounds with high-level combinators
 description:        'lambdasound' can generate all kinds of sounds, play them and save them as wav or pcm data.
                     Sound can be manipulated in both a low and high-level way. It is possible to 
@@ -135,7 +135,7 @@
         lambdasound,
         tasty >= 1.4 && < 1.5,
         tasty-bench >= 0.3.5 && < 0.4,
-        vector >= 0.13.0 && < 0.14
+        massiv
     ghc-options: -O2
 
 source-repository head
diff --git a/src/LambdaSound.hs b/src/LambdaSound.hs
--- a/src/LambdaSound.hs
+++ b/src/LambdaSound.hs
@@ -1,9 +1,11 @@
 -- |
--- Library users should implement this module (@import LambdaSound@).
+-- Library users should implement this module ( @import LambdaSound@ ).
 --
 -- This module packages all the functions from the other modules and reexports them.
--- A good starting place to explore the documentation is the *LambdaSound.Sound* module which
+-- A good starting point to explore the documentation is the @LambdaSound.Sound@ module which
 -- exports all the datatypes and many of the useful combinators you will use.
+-- 
+-- The @LambdaSound.Sample@ module contains some simple sound samples which you can play with the @LambdaSound.Play@ module. 
 module LambdaSound
   ( -- * Sounds
     module Sound,
diff --git a/src/LambdaSound/Cache.hs b/src/LambdaSound/Cache.hs
--- a/src/LambdaSound/Cache.hs
+++ b/src/LambdaSound/Cache.hs
@@ -17,10 +17,10 @@
 import System.FilePath (joinPath)
 
 -- | Caches a sound. If the sound is cached, then
--- the sound gets read from the XDG data directory and does not have to
+-- the sound gets read from the XDG cache directory and does not have to
 -- be computed again.
--- It might load a cached sound which is not the same
--- as the computed one, but this should be very unlikely
+-- 
+-- It might load a cached sound which which is incorrect, but this should be very unlikely
 cache :: Sound d Pulse -> Sound d Pulse
 cache (TimedSound d msc) = TimedSound d $ cacheComputation msc
 cache (InfiniteSound msc) = InfiniteSound $ cacheComputation msc
diff --git a/src/LambdaSound/Create.hs b/src/LambdaSound/Create.hs
--- a/src/LambdaSound/Create.hs
+++ b/src/LambdaSound/Create.hs
@@ -1,16 +1,16 @@
 module LambdaSound.Create
-  ( -- *** Basic sounds
+  ( -- * Basic sounds
     time,
     progress,
     sampleIndex,
     constant,
     silence,
 
-    -- *** Iterating
+    -- * Iterating
     iterateSound,
     iterateSoundPulse,
 
-    -- *** Unfolding
+    -- * Unfolding
     unfoldlSound,
     unfoldlSoundPulse,
     unfoldrSound,
diff --git a/src/LambdaSound/Note.hs b/src/LambdaSound/Note.hs
--- a/src/LambdaSound/Note.hs
+++ b/src/LambdaSound/Note.hs
@@ -4,6 +4,8 @@
 
 import LambdaSound.Sound
 
+-- * Semitones
+
 -- | Semitones are tones like 'c4', 'd4' or 'c5'.
 -- The semitone is used to determine the hz of the tone based on 'pitchStandard'
 newtype Semitone = Semitone Int deriving (Show, Eq, Num, Ord, Enum)
@@ -18,8 +20,10 @@
 
 -- | Raise a sound by the given amount of semitones.
 -- This only works for sounds which use the period length given
--- in the compute step of the sound. 'pulse' works but 'noise' does not.
+-- in the compute step of the sound. 'sineWave' works but 'noise' does not.
+--
 -- For example:
+--
 -- > raiseSemitones 2 (asNote pulse c3) = asNote pulse d3
 raiseSemitones :: Int -> Sound d Pulse -> Sound d Pulse
 raiseSemitones x = raise (2 ** (fromIntegral x / 12))
@@ -29,7 +33,9 @@
 diminishSemitones x = raiseSemitones (-x)
 
 -- | Transforms a function taking a 'Hz' to one taking a 'Semitone'.
--- Should be used with 'pulse' or 'harmonic'
+-- Should be used like the following:
+--
+-- > asNote sineWave c4
 asNote :: (Hz -> a) -> Semitone -> a
 asNote f s = f (semitoneToHz s)
 
@@ -96,16 +102,15 @@
 a7 = 36
 b7 = 38
 
--- ** Notes
+-- * Notes
 
 -- | These are durations for the corresponding note lenghts
 -- assuming 60 bpm.
 --
 -- If you know that a sound has 60 bpm, you can easily scale to
 -- different bpm with 'scaleDuration':
--- @
--- scaleDuration (wantedBPM / 60) soundWith60BPM
--- @
+--
+-- > scaleDuration (wantedBPM / 60) soundWith60BPM
 wholeNote, halfNote, quarterNote, eightNote :: Duration
 wholeNote = 1
 halfNote = 1 / 2
diff --git a/src/LambdaSound/Sound.hs b/src/LambdaSound/Sound.hs
--- a/src/LambdaSound/Sound.hs
+++ b/src/LambdaSound/Sound.hs
@@ -1,7 +1,7 @@
 -- |
 -- This module exports all needed datatypes and all the combinators needed to manipulate them.
 module LambdaSound.Sound
-  ( -- ** Sound types
+  ( -- * Sound types
     Sound (..),
     SoundDuration (..),
     Pulse (..),
@@ -13,7 +13,8 @@
     Time (..),
     DetermineDuration,
 
-    -- ** Make new sounds
+    -- * Make new sounds
+
     -- Also take a look at @LambdaSound.Create@!
     makeSound,
     makeSoundVector,
@@ -21,25 +22,25 @@
     fillWholeSoundST,
     computeOnce,
 
-    -- ** Sounds in sequence
+    -- * Sounds in sequence
     timedSequentially,
     (>>>),
     sequentially,
     infiniteSequentially,
 
-    -- ** Sounds in parallel
+    -- * Sounds in parallel
     parallel2,
     parallel,
 
-    -- ** Volume
+    -- * Volume
     amplify,
     reduce,
 
-    -- ** Pitch
+    -- * Pitch
     raise,
     diminish,
 
-    -- ** Duration
+    -- * Duration
     setDuration,
     (|->),
     getDuration,
@@ -47,23 +48,27 @@
     dropDuration,
     adoptDuration,
 
-    -- ** Sample order
+    -- * Sample order
     reverseSound,
     dropSound,
     takeSound,
 
-    -- ** Zipping
+    -- * Zipping
     zipSoundWith,
     zipSound,
 
-    -- ** Change play behavior of a sound
+    -- * Change play behavior of a sound
     changeTempo,
     changeTempoM,
 
-    -- ** Modify the samples of a sound
+    -- * Modify the samples of a sound
     modifyWholeSound,
     modifyWholeSoundST,
+
+    -- * Access the samples of a sound
     withSamplingInfo,
+    withSampledSound,
+    withSampledSoundPulse,
   )
 where
 
@@ -76,9 +81,9 @@
 import LambdaSound.Sound.Types
 import System.IO.Unsafe (unsafePerformIO)
 
--- | Some 'Sound's have a different while others do not.
--- 'I'nfinite 'Sound's have no duration.
+-- | 'Sound's may have a duration attached to them.
 -- 'T'imed 'Sound's have a duration.
+-- 'I'nfinite 'Sound's have no duration.
 data SoundDuration = I | T
 
 -- | Determines the duration of two sounds when they are combined
@@ -161,7 +166,7 @@
     computeSequentially (coerce $ d1 / (d1 + d2)) c1 c2
 
 -- | Append two infinite sounds where the 'Percentage' in the range @[0,1]@
--- specified when the first sound ends and the next begins.
+-- specifies when the first sound ends and the next begins.
 infiniteSequentially :: Percentage -> Sound I Pulse -> Sound I Pulse -> Sound I Pulse
 infiniteSequentially factor' (InfiniteSound c1) (InfiniteSound c2) =
   InfiniteSound $
@@ -374,6 +379,16 @@
 -- | Access the sample rate of an infinite sound
 withSamplingInfo :: (SamplingInfo -> Sound d a) -> Sound I a
 withSamplingInfo f = InfiniteSound $ withSamplingInfoCS (getCS . f)
+
+-- | Access the samples of a sound.
+--
+-- The pulse version is slightly faster since you get a storable vector
+withSampledSoundPulse :: Sound T Pulse -> (M.Vector M.S Pulse -> Sound I a) -> Sound I a
+withSampledSoundPulse (TimedSound duration cs) = InfiniteSound . withSampledSoundPulseCS duration cs . fmap getCS
+
+-- | Access the samples of a sound.
+withSampledSound :: Sound T a -> (M.Vector M.D a -> Sound I b) -> Sound I b
+withSampledSound (TimedSound duration cs) = InfiniteSound . withSampledSoundCS duration cs . fmap getCS
 
 -- | Calculate sound samples based on their index.
 -- Take a look at @LambdaSound.Create@ for other creation functions.
diff --git a/src/LambdaSound/Sound/ComputeSound.hs b/src/LambdaSound/Sound/ComputeSound.hs
--- a/src/LambdaSound/Sound/ComputeSound.hs
+++ b/src/LambdaSound/Sound/ComputeSound.hs
@@ -45,6 +45,29 @@
    in compute si memo
 {-# INLINE withSamplingInfoCS #-}
 
+withSampledSoundPulseCS :: Duration -> ComputeSound Pulse -> (M.Vector M.S Pulse -> ComputeSound a) -> ComputeSound a
+withSampledSoundPulseCS duration cs f = ComputeSound $ \si memo -> do
+  let sampleSI = makeSamplingInfo si.sampleRate duration
+  (writeSamples, ci) <- asWriteResult cs sampleSI memo
+  dest <- MU.unsafeMallocMArray (M.Sz1 sampleSI.samples)
+  writeSamples dest
+  samples <- MU.unsafeFreeze M.Seq dest
+  let (ComputeSound compute) = f samples
+  (res, _) <- compute si memo
+  stableF <- makeSomeStableName f
+  pure (res, ComputationInfoWithSampledSound stableF ci)
+{-# INLINE withSampledSoundPulseCS #-}
+
+withSampledSoundCS :: Duration -> ComputeSound a -> (M.Vector M.D a -> ComputeSound b) -> ComputeSound b
+withSampledSoundCS duration cs f = ComputeSound $ \si memo -> do
+  let sampleSI = makeSamplingInfo si.sampleRate duration
+  (delayedVector, ci) <- asDelayedResult cs sampleSI memo
+  let (ComputeSound compute) = f delayedVector
+  (res, _) <- compute si memo
+  stableF <- makeSomeStableName f
+  pure (res, ComputationInfoWithSampledSound stableF ci)
+{-# INLINE withSampledSoundCS #-}
+
 mergeDelayedResult :: (SamplingInfo -> M.Vector M.D a -> M.Vector M.D b -> M.Vector M.D c) -> ComputeSound a -> ComputeSound b -> ComputeSound c
 mergeDelayedResult merge cs1 cs2 = ComputeSound $ \si memo -> do
   stableMerge <- makeSomeStableName merge
@@ -65,11 +88,11 @@
     ( WriteResult $ \dest -> do
         writeResult1 $ MU.unsafeLinearSliceMArray 0 (M.Sz1 splitIndex) dest
         writeResult2 $ MU.unsafeLinearSliceMArray splitIndex (M.Sz1 $ si.samples - splitIndex) dest,
-      ComputationInfoSequentially ci1 ci2
+      ComputationInfoSequentially factor ci1 ci2
     )
 {-# INLINE computeSequentially #-}
 
-computeParallel :: ComputeSound Pulse -> Float -> ComputeSound Pulse -> ComputeSound Pulse
+computeParallel :: ComputeSound Pulse -> Percentage -> ComputeSound Pulse -> ComputeSound Pulse
 computeParallel c1 factor c2 = ComputeSound $ \si memo -> do
   let c2N = round $ factor * fromIntegral si.samples
   (delayedResult1, p1) <- asDelayedResult c1 si memo
@@ -78,7 +101,7 @@
     ( if si.samples == c2N
         then DelayedResult $ M.zipWith (+) delayedResult1 delayedResult2
         else DelayedResult $ M.imap (\index -> (+) $ if index < c2N then MU.unsafeIndex delayedResult2 index else 0) delayedResult1,
-      ComputationInfoParallel p1 p2
+      ComputationInfoParallel factor p1 p2
     )
 {-# INLINE computeParallel #-}
 
@@ -225,14 +248,15 @@
 data ComputationInfo
   = ComputationInfoZip SomeStableName ComputationInfo ComputationInfo
   | ComputationInfoMap SomeStableName ComputationInfo
-  | ComputationInfoSequentially ComputationInfo ComputationInfo
-  | ComputationInfoParallel ComputationInfo ComputationInfo
+  | ComputationInfoSequentially Percentage ComputationInfo ComputationInfo
+  | ComputationInfoParallel Percentage ComputationInfo ComputationInfo
   | ComputationInfoMakeDelayedResult SomeStableName
   | ComputationInfoMapDelayedResult SomeStableName ComputationInfo
   | ComputationInfoMergeDelayedResult SomeStableName ComputationInfo ComputationInfo
   | ComputationInfoMapMemory SomeStableName ComputationInfo
   | ComputationInfoFillMemory SomeStableName
   | ComputationInfoChangeSamplingInfo SomeStableName ComputationInfo
+  | ComputationInfoWithSampledSound  SomeStableName ComputationInfo
   deriving (Eq, Generic, Show)
 
 instance Hashable ComputationInfo
