diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,4 @@
+# 0.7.0
+- use ByteString for in-memory sample loading
+- fix: c++ mixer init caused segfaults sometimes
+- use PulseAudio backend on Linux
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# Overview
+
+ProteaAudio is a stereo audio mixer/playback library
+for Linux (native ALSA, Jack, and OSS),
+Macintosh OS X (CoreAudio and Jack),
+and Windows (DirectSound and ASIO) operating systems.
+
+
+# Example
+
+```haskell
+import Control.Monad
+import System.Environment
+import System.FilePath
+import qualified Data.ByteString as SB
+import Control.Concurrent
+
+import Sound.ProteaAudio
+
+waitPayback = do
+  n <- soundActive
+  when  (n > 0) $ do
+    threadDelay 1000000
+    waitPayback
+
+main = do
+    args <- getArgs
+    filename <- case args of
+      a : _ -> pure a
+      _ -> fail "usage: proteaaudio-play SAMPLE_FILE_NAME"
+
+    result <- initAudio 64 44100 1024 -- max channels, mixing frequency, mixing buffer size
+    unless result $ fail "failed to initialize the audio system"
+
+    -- (A) load sample from file
+    sampleA <- sampleFromFile filename 1.0 -- volume
+
+    soundPlay sampleA 1 1 0 1 -- left volume, right volume, time difference between left and right, pitch factor for playback
+    waitPayback
+
+    -- (B) load from memory buffer
+    buffer <- SB.readFile filename
+    sampleB <- case takeExtension filename of
+      ".ogg" -> sampleFromMemoryOgg buffer 1.0
+      ".wav" -> sampleFromMemoryWav buffer 1.0
+
+    soundPlay sampleB 1 1 0 1 -- left volume, right volume, time difference between left and right, pitch factor for playback
+    waitPayback
+
+    finishAudio
+```
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/Sound/ProteaAudio.chs b/Sound/ProteaAudio.chs
--- a/Sound/ProteaAudio.chs
+++ b/Sound/ProteaAudio.chs
@@ -1,3 +1,9 @@
+{-|
+    ProteaAudio is a stereo audio mixer/playback library
+    for Linux (native ALSA, Jack, and OSS),
+    Macintosh OS X (CoreAudio and Jack),
+    and Windows (DirectSound and ASIO) operating systems.
+-}
 {-#LANGUAGE ForeignFunctionInterface#-}
 #include "proteaaudio_binding.h"
 module Sound.ProteaAudio (
@@ -19,24 +25,108 @@
 
 import Foreign
 import Foreign.C
+import Data.ByteString (ByteString, useAsCStringLen)
 
+-- | audio sample handle
 newtype Sample = Sample {#type sample_t#}
 
 toSample s = Sample s
 fromSample (Sample s) = s
 
-{#fun initAudio {`Int', `Int', `Int'} -> `Bool'#}
+-- | initializes the audio system
+{#fun initAudio
+    { `Int' -- ^ the maximum number of sounds that are played parallely. Computation time is linearly correlated to this factor.
+    , `Int' -- ^ sample frequency of the playback in Hz. 22050 corresponds to FM radio 44100 is CD quality. Computation time is linearly correlated to this factor.
+    , `Int' -- ^ the number of bytes that are sent to the sound card at once. Low numbers lead to smaller latencies but need more computation time (thread switches). If a too small number is chosen, the sounds might not be played continuously. The default value 512 guarantees a good latency below 40 ms at 22050 Hz sample frequency.
+    } -> `Bool' -- ^ returns True on success
+#}
+
+-- | releases the audio device and cleans up resources
 {#fun finishAudio {} -> `()'#}
-{#fun loaderAvailable {`String'} -> `Bool'#}
-{#fun sampleFromMemoryWav {id `Ptr CChar', `Int', `Float'} -> `Sample' toSample#}
-{#fun sampleFromMemoryOgg {id `Ptr CChar', `Int', `Float'} -> `Sample' toSample#}
-{#fun sampleFromFile {`String', `Float'} -> `Sample' toSample#}
 
-{#fun volume {`Float', `Float'} -> `()'#}
+-- | checks if loader for this file type is available
+{#fun loaderAvailable
+  { `String' -- ^ file extension (e.g. ogg)
+  } -> `Bool'
+#}
+
+-- | loads wav sound sample from memory buffer
+{#fun _sampleFromMemoryWav
+  { id `Ptr CChar' -- ^ memory buffer pointer
+  , `Int' -- ^ memory buffer size in bytes
+  , `Float' -- ^ volume
+  } -> `Sample' toSample -- ^ returns handle
+#}
+
+-- | loads ogg sound sample from memory buffer
+{#fun _sampleFromMemoryOgg
+  { id `Ptr CChar' -- ^ memory buffer pointer
+  , `Int' -- ^ memory buffer size in bytes
+  , `Float' -- ^ volume
+  } -> `Sample' toSample -- ^ returns handle
+#}
+
+-- | loads wav sound sample from memory buffer
+sampleFromMemoryWav :: ByteString -- ^ wav sample data
+                    -> Float -- ^ volume
+                    -> IO Sample -- ^ return sample handle
+sampleFromMemoryWav wavData volume = useAsCStringLen wavData $ \(ptr, size) -> _sampleFromMemoryWav ptr size volume
+
+-- | loads ogg sound sample from memory buffer
+sampleFromMemoryOgg :: ByteString -- ^ ogg sample data
+                    -> Float -- ^ volume
+                    -> IO Sample -- ^ return sample handle
+sampleFromMemoryOgg oggData volume = useAsCStringLen oggData $ \(ptr, size) -> _sampleFromMemoryOgg ptr size volume
+
+-- | loads a sound sample from file
+{#fun sampleFromFile
+  { `String' -- ^ sample filepath
+  , `Float' -- ^ volume
+  } -> `Sample' toSample -- ^ returns handle
+#}
+
+-- | set mixer volume
+{#fun volume
+  { `Float' -- ^ left
+  , `Float' -- ^ right
+  } -> `()'
+#}
+
+-- | number of currently active sounds
 {#fun soundActive {} -> `Int'#}
+
+-- | stops all sounds immediately
 {#fun soundStopAll {} -> `()'#}
 
-{#fun soundLoop {fromSample `Sample', `Float', `Float', `Float', `Float'} -> `()'#}
-{#fun soundPlay {fromSample `Sample', `Float', `Float', `Float', `Float'} -> `()'#}
-{#fun soundUpdate {fromSample `Sample', `Float', `Float', `Float', `Float'} -> `Bool'#}
+-- | plays a specified sound sample continuously and sets its parameters
+{#fun soundLoop
+  { fromSample `Sample' -- ^ handle of a previously loaded sample
+  , `Float' -- ^ left volume
+  , `Float' -- ^ right volume
+  , `Float' -- ^ time difference between left and right channel in seconds. Use negative values to specify a delay for the left channel, positive for the right
+  , `Float' -- ^ pitch factor for playback. 0.5 corresponds to one octave below, 2.0 to one above the original sample
+  } -> `()'
+#}
+
+-- | plays a specified sound sample once and sets its parameters
+{#fun soundPlay
+  { fromSample `Sample' -- ^ handle of a previously loaded sample
+  , `Float' -- ^ left volume
+  , `Float' -- ^ right volume
+  , `Float' -- ^ time difference between left and right channel in seconds. Use negative values to specify a delay for the left channel, positive for the right
+  , `Float' -- ^ pitch factor for playback. 0.5 corresponds to one octave below, 2.0 to one above the original sample
+  } -> `()'
+#}
+
+-- | updates parameters of a specified sound
+{#fun soundUpdate
+  { fromSample `Sample' -- ^ handle of a currently active sound
+  , `Float' -- ^ left volume
+  , `Float' -- ^ right volume
+  , `Float' -- ^ time difference between left and right channel in seconds. Use negative values to specify a delay for the left channel, positive for the right
+  , `Float' -- ^ pitch factor for playback. 0.5 corresponds to one octave below, 2.0 to one above the original sample
+  } -> `Bool' -- ^ return True in case the parameters have been updated successfully
+#}
+
+-- | stops a specified sound immediately
 {#fun soundStop {fromSample `Sample'} -> `Bool'#}
diff --git a/cbits/proAudioRt.cpp b/cbits/proAudioRt.cpp
--- a/cbits/proAudioRt.cpp
+++ b/cbits/proAudioRt.cpp
@@ -49,6 +49,12 @@
 	oParams.nChannels = 2; // stereo
 	oParams.firstChannel = 0;
 
+    // initialize tracks:
+    m_nSound=nTracks;
+    ma_sound=new _AudioTrack[m_nSound];
+	memset(ma_sound,0,m_nSound*sizeof(_AudioTrack));
+	m_freqOut = frequency;
+
 	try {
 		m_dac.openStream( &oParams, NULL, RTAUDIO_SINT16, frequency, &chunkSize, &cbMix, (void *)this );
 		m_dac.startStream();
@@ -59,11 +65,6 @@
 		return;
 	}
 
-    // initialize tracks:
-    m_nSound=nTracks;
-    ma_sound=new _AudioTrack[m_nSound];
-	memset(ma_sound,0,m_nSound*sizeof(_AudioTrack));
-	m_freqOut = frequency;
 }
 
 DeviceAudioRt::~DeviceAudioRt() {
diff --git a/cbits/proteaaudio_binding.cpp b/cbits/proteaaudio_binding.cpp
--- a/cbits/proteaaudio_binding.cpp
+++ b/cbits/proteaaudio_binding.cpp
@@ -82,7 +82,7 @@
     return (int)audio.sampleFromFile(filename, volume);
 }
 
-sample_t sampleFromMemoryWav(char *data, int size, float volume) {
+sample_t _sampleFromMemoryWav(char *data, int size, float volume) {
     DeviceAudio & audio = DeviceAudio::singleton();
     if((&audio) == 0) return 0;
     AudioSample* pSample = loadWavFromMemory((unsigned char*)data, size);
@@ -92,7 +92,7 @@
     return (int)ret;
 }
 
-sample_t sampleFromMemoryOgg(char *data, int size, float volume) {
+sample_t _sampleFromMemoryOgg(char *data, int size, float volume) {
     DeviceAudio & audio = DeviceAudio::singleton();
     if((&audio) == 0) return 0;
     AudioSample* pSample = loadOggFromMemory((unsigned char*)data, size);
diff --git a/cbits/proteaaudio_binding.h b/cbits/proteaaudio_binding.h
--- a/cbits/proteaaudio_binding.h
+++ b/cbits/proteaaudio_binding.h
@@ -8,8 +8,8 @@
 void finishAudio();
 int loaderAvailable(char* suffix);
 void volume(float left, float right);
-sample_t sampleFromMemoryWav(char *data, int size, float volume);
-sample_t sampleFromMemoryOgg(char *data, int size, float volume);
+sample_t _sampleFromMemoryWav(char *data, int size, float volume);
+sample_t _sampleFromMemoryOgg(char *data, int size, float volume);
 sample_t sampleFromFile(char* filename, float volume);
 int soundActive();
 void soundStopAll();
diff --git a/example/play.hs b/example/play.hs
--- a/example/play.hs
+++ b/example/play.hs
@@ -6,22 +6,34 @@
 
 import Sound.ProteaAudio
 
+waitPayback = do
+  n <- soundActive
+  when  (n > 0) $ do
+    threadDelay 1000000
+    waitPayback
+
 main = do
     args <- getArgs
-    initAudio 64 44100 1024
-    let fname = head args
-    -- load from file
-    smp <- sampleFromFile fname 1.0 -- volume
+    filename <- case args of
+      a : _ -> pure a
+      _ -> fail "usage: proteaaudio-play SAMPLE_FILE_NAME"
 
-    buf <- SB.readFile fname
-    -- load from memory buffer
-    smp' <- case takeExtension fname of
-      ".ogg" -> SB.useAsCStringLen buf $ \(p,i) -> sampleFromMemoryOgg p i 1
-      ".wav" -> SB.useAsCStringLen buf $ \(p,i) -> sampleFromMemoryWav p i 1
+    result <- initAudio 64 44100 1024 -- max channels, mixing frequency, mixing buffer size
+    unless result $ fail "failed to initialize the audio system"
 
-    soundPlay smp' 1 1 0 1
-    let loop = do
-            n <- soundActive
-            when  (n > 0) $ threadDelay 1000000 >> loop
-    loop
+    -- (A) load sample from file
+    sampleA <- sampleFromFile filename 1.0 -- volume
+
+    soundPlay sampleA 1 1 0 1 -- left volume, right volume, time difference between left and right, pitch factor for playback
+    waitPayback
+
+    -- (B) load from memory buffer
+    buffer <- SB.readFile filename
+    sampleB <- case takeExtension filename of
+      ".ogg" -> sampleFromMemoryOgg buffer 1.0
+      ".wav" -> sampleFromMemoryWav buffer 1.0
+
+    soundPlay sampleB 1 1 0 1 -- left volume, right volume, time difference between left and right, pitch factor for playback
+    waitPayback
+
     finishAudio
diff --git a/proteaaudio.cabal b/proteaaudio.cabal
--- a/proteaaudio.cabal
+++ b/proteaaudio.cabal
@@ -1,5 +1,5 @@
 Name:                proteaaudio
-Version:             0.6.5
+Version:             0.7.0
 Synopsis:            Simple audio library for Windows, Linux, OSX.
 Description:         Simple audio library for Windows, Linux, OSX. Supports Ogg and Wav playback and multichannel mixing.
 License:             BSD3
@@ -8,7 +8,7 @@
 Maintainer:          csaba.hruska@gmail.com
 Stability:           Experimental
 Category:            Sound
-Tested-With:         GHC == 7.10.3
+Tested-With:         GHC == 8.0.2
 Cabal-Version:       >= 1.10
 Build-Type:          Simple
 
@@ -42,6 +42,9 @@
 
   example/play.hs
 
+  README.md
+  CHANGELOG.md
+
 Flag example
   Description: Build with example
   Default: False
@@ -51,7 +54,9 @@
   location: https://github.com/csabahruska/proteaaudio
 
 Library
-  Build-Depends:        base >= 4 && < 5
+  Build-Depends:        base >= 4 && < 5,
+                        bytestring == 0.10.*
+
   default-language:     Haskell2010
 
   Build-tools:          c2hs
@@ -70,15 +75,13 @@
     CC-Options:         "-D__WINDOWS_DS__"
     Extra-Libraries:    stdc++ ole32 dsound winmm
   if os(linux)
-    CC-Options:         "-D__LINUX_ALSA__ -D__LINUX_PULSE__ -D__LINUX_OSS__"
-    Extra-Libraries:    stdc++ pthread asound
+    CC-Options:         "-D__LINUX_PULSE__"
+    Extra-Libraries:    stdc++ pthread pulse-simple pulse
   if os(darwin)
     CC-Options:         "-D__MACOSX_CORE__"
     Extra-Libraries:    stdc++ pthread
     Frameworks:         CoreFoundation CoreAudio
 
-  ghc-options: -O2
-
 executable proteaaudio-play
   if flag(example)
     Buildable: True
@@ -91,6 +94,6 @@
 
   build-depends:
     base >= 4 && < 5,
-    filepath >=1.4 && <1.5,
+    filepath >=1.4 && <2,
     bytestring == 0.10.*,
     proteaaudio
