diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,105 @@
+## v0.5.4
+
+  * Program will always also look for songs in the folder it's in
+  * Add option and script to export all backing tracks without combining them
+
+## v0.5.3.2
+
+Mac-only release, fixes some issues on Sierra
+
+## v0.5.3
+
+Added support for "Bass 2", "Vocals" (instead of "Vocal"),
+and "Vocal 1"/"Vocal 2" (instead of "Vocal"/"B Vocals").
+
+## v0.5.2
+
+Added the ability to export the metronome click track.
+Available via the `-m` option, or via the `-x` or `-b` full backup options
+(including the `easy-export` script on Windows/Mac).
+
+## v0.5.1
+
+Added a `-b` option for backing up an entire library of songs.
+
+## v0.5.0.3
+
+Fixed some bugs in both audio and image decoding.
+
+## v0.5.0.1
+
+Fixed a bug in reading the `beats.plist` file
+(not actually used in the executable).
+
+## v0.5
+
+  * Fixed a bug where `"Song Title "` wasn't considered the same as `"Song Title"`
+  * Much internal cleanup, smaller executable size
+  * Library: added some more Jammit types (beats, ghost beats, sections)
+
+## v0.4.1.1
+
+Fixes for GHC 7.10 (no new functionality).
+
+## v0.4.1
+
+Uses [`conduit-audio`](http://hackage.haskell.org/package/conduit-audio),
+and exposes the audio file as an
+[`AudioStream`](http://hackage.haskell.org/package/conduit-audio-0.1/docs/Data-Conduit-Audio.html#t:AudioSource).
+
+## v0.4
+
+  * Doesn't require ImageMagick or SoX anymore!
+    Thanks to [JuicyPixels](https://hackage.haskell.org/package/JuicyPixels),
+    [HPDF](https://hackage.haskell.org/package/HPDF),
+    [conduit](https://hackage.haskell.org/package/conduit),
+    and audio code ported from [aifc2wav](http://sed.free.fr/aifc2wav.html).
+  * Prints better instructions.
+  * Prints what it is doing during each step of the `-x dir` export option.
+  * Error if the search parameters don't narrow down the library
+    to exactly one song.
+
+## v0.3.2
+
+Fixes for Windows, other platforms are unchanged:
+
+  * Use `wchar_t` for C functions to support non-ASCII filenames
+  * Look for SoX in Program Files (the installer doesn't put it in the `PATH`)
+
+## v0.3.1
+
+  * Added support for Drums 1, Drums 2 and Organ parts
+  * Better argument handling (quits on unrecognized argument)
+
+## v0.3
+
+Split the package into a library and an executable.
+No functional changes to the executable.
+
+## v0.2.0.1
+
+Documentation, packaging, and version bounds improvements.
+
+## v0.2
+
+  * Proper Mac support (knows the official library location).
+  * Changed the long forms of some commands for consistency.
+  * Removed `-u` and `-b`, replaced with a simple `-c` option which does a dry
+    run of audio extraction. That is, it does no audio conversion, but exits
+    with a code of 0 only if all specified audio parts are found.
+  * Fixed a crash on very large libraries.
+
+## v0.1.1
+
+  * `-u` and `-b` audio options for
+    [`onyxite-customs`](https://github.com/mtolly/onyxite-customs) project
+  * `-T` and `-R` perform exact title/artist search,
+    instead of existing `-t` and `-r` "case-insensitive substring" search
+
+## v0.1
+
+Binary compiled with GHC 7.6.3 32-bit on Windows 7 64-bit.
+Should also work on Wine.
+You must install [ImageMagick](http://www.imagemagick.org/script/index.php)
+and [SoX](http://sox.sourceforge.net/)
+for sheet music and audio export respectively.
diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,28 +1,28 @@
 {-# LANGUAGE CPP #-}
 module Main (main) where
 
+import           Control.Applicative    ((<|>))
+import           Control.Monad          (forM_, unless, (>=>))
+import           Data.Char              (toLower)
+import           Data.List              (nub, partition, sort)
+import           Data.Maybe             (catMaybes, fromMaybe, mapMaybe,
+                                         maybeToList)
+import           Data.Version           (showVersion)
+import qualified Paths_jammittools      as Paths
+import           Sound.Jammit.Base
+import           Sound.Jammit.Export
+import qualified System.Console.GetOpt  as Opt
+import           System.Directory       (createDirectoryIfMissing)
+import qualified System.Environment     as Env
+import           System.Exit            (exitFailure)
+import           System.FilePath        (makeValid, takeDirectory, (<.>), (</>))
+import           Text.PrettyPrint.Boxes (hsep, left, render, text, top, vcat,
+                                         (/+/))
+
 #if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>))
+import           Control.Applicative    ((<$>))
 #endif
-import Control.Applicative ((<|>))
-import Control.Monad ((>=>), forM_, unless)
-import Data.Char (toLower)
-import Data.List (sort, nub, partition)
-import Data.Maybe (catMaybes, mapMaybe, fromMaybe, listToMaybe)
-import Data.Version (showVersion)
-import qualified System.Console.GetOpt as Opt
-import qualified System.Environment as Env
-import System.Exit (exitFailure)
 
-import System.Directory (createDirectoryIfMissing)
-import System.FilePath ((</>), makeValid)
-import Text.PrettyPrint.Boxes
-  (text, vcat, left, render, hsep, top, (/+/))
-
-import Sound.Jammit.Base
-import Sound.Jammit.Export
-import qualified Paths_jammittools as Paths
-
 printUsage :: IO ()
 printUsage = do
   prog <- Env.getProgName
@@ -59,7 +59,7 @@
             backingOrder = [Drums, Guitar, Keyboard, Bass, Vocal]
             isGuitar p = elem (partToInstrument p) [Guitar, Bass]
             (gtrs, nongtrs) = partition isGuitar [minBound .. maxBound]
-            chosenBacking = listToMaybe $ flip mapMaybe backingOrder $ \i ->
+            backingTracks = flip mapMaybe backingOrder $ \i ->
               case getOneResult (Without i) audios of
                 Left  _  -> Nothing
                 Right fp -> Just (i, fp)
@@ -68,7 +68,7 @@
             (Right note, Right tab) -> let
               parts = [note, tab]
               systemHeight = sum $ map snd parts
-              fout = dout </> drop 4 (map toLower (show p) ++ ".pdf")
+              fout = dout </> drop 4 (map toLower $ show p) <.> "pdf"
               in do
                 putStrLn $ "Exporting notation & tab for " ++ show p
                 runSheet [note, tab] (getPageLines systemHeight args) fout
@@ -77,7 +77,7 @@
           case getOneResult (Notation p) sheets of
             Left  _    -> return ()
             Right note -> let
-              fout = dout </> drop 4 (map toLower (show p) ++ ".pdf")
+              fout = dout </> drop 4 (map toLower $ show p) <.> "pdf"
               in do
                 putStrLn $ "Exporting notation for " ++ show p
                 runSheet [note] (getPageLines (snd note) args) fout
@@ -85,18 +85,23 @@
           case getOneResult (Only p) audios of
             Left  _  -> return ()
             Right fp -> let
-              fout = dout </> drop 4 (map toLower (show p) ++ ".wav")
+              fout = dout </> drop 4 (map toLower $ show p) <.> "wav"
               in do
                 putStrLn $ "Exporting audio for " ++ show p
                 runAudio [fp] [] fout
-        case chosenBacking of
-          Nothing            -> return ()
-          Just (inst, fback) -> let
-            others = [ fp | (Only p, fp) <- audios, partToInstrument p /= inst ]
-            fout = dout </> "backing.wav"
-            in do
-              putStrLn "Exporting backing audio (could take a while)"
-              runAudio [fback] others fout
+        if rawBackings args
+          then forM_ backingTracks $ \(inst, fback) -> do
+            putStrLn $ "Exporting backing track for " ++ show inst
+            let fout = dout </> "backing-" ++ map toLower (show inst) <.> "wav"
+            runAudio [fback] [] fout
+          else case backingTracks of
+            []                -> return ()
+            (inst, fback) : _ -> let
+              others = [ fp | (Only p, fp) <- audios, partToInstrument p /= inst ]
+              fout = dout </> "backing.wav"
+              in do
+                putStrLn "Exporting backing audio (could take a while)"
+                runAudio [fback] others fout
         clickTracks <- mapM loadBeats $ map (\(fp, _, _) -> fp) matches
         case catMaybes clickTracks of
           [] -> return ()
@@ -190,14 +195,13 @@
 -- to filter it.
 searchResults :: Args -> IO Library
 searchResults args = do
-  jmt <- case jammitDir args of
-    Just j  -> return j
+  exeDir <- takeDirectory <$> Env.getExecutablePath
+  jmt    <- case jammitDir args of
+    Just j  -> return [j]
     Nothing -> Env.lookupEnv "JAMMIT" >>= \mv -> case mv of
-      Just j -> return j
-      Nothing -> let
-        err = "Couldn't find Jammit directory. Try -j or the env var JAMMIT"
-        in fromMaybe (error err) <$> findJammitDir
-  db <- loadLibrary jmt
+      Just j  -> return [j]
+      Nothing -> maybeToList <$> findJammitDir
+  db <- concat <$> mapM loadLibrary (exeDir : jmt)
   return $ filterLibrary args db
 
 -- | Checks that the search actually narrowed down the library to a single song.
@@ -273,6 +277,9 @@
   , Opt.Option ['c'] ["check"]
     (Opt.NoArg $ \a -> a { function = CheckPresence })
     "function: check presence of audio parts"
+  , Opt.Option [] ["raw"]
+    (Opt.NoArg $ \a -> a { rawBackings = True })
+    "when exporting song/library, extract all individual backing tracks"
   ]
 
 data Args = Args
@@ -282,6 +289,7 @@
   , pageLines     :: Maybe Int
   , jammitDir     :: Maybe FilePath
   , function      :: Function
+  , rawBackings   :: Bool
   }
 
 data Function
@@ -303,6 +311,7 @@
   , pageLines     = Nothing
   , jammitDir     = Nothing
   , function      = PrintUsage
+  , rawBackings   = False
   }
 
 partToChar :: Part -> Char
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@
     # On Windows and OS X, the official app's library location is used
     # if you do not specify this flag.
     # You can also specify the environment variable JAMMIT.
+    # Songs in the same folder as the program will also always be found.
 
     -T "My Song"
     # Exact search on title, instead of -t which is case-insensitive substring.
@@ -69,6 +70,10 @@
     # One system contains a line from each individual part.
     # If this flag is not given, an appropriate number of systems will be chosen
     # to get close to an 8.5" by 11" page ratio.
+
+    --raw
+    # For -x and -b options, exports all original backing tracks separately
+    # instead of producing a combined one.
 
 Instrument parts are given by this somewhat terse syntax:
 
diff --git a/jammittools.cabal b/jammittools.cabal
--- a/jammittools.cabal
+++ b/jammittools.cabal
@@ -1,5 +1,5 @@
 Name:               jammittools
-Version:            0.5.3.2
+Version:            0.5.4
 Synopsis:           Export sheet music and audio from Windows/Mac app Jammit
 Description:
 
@@ -20,7 +20,9 @@
 Category:           Sound
 Homepage:           https://github.com/mtolly/jammittools
 Bug-Reports:        https://github.com/mtolly/jammittools/issues
-Extra-Source-Files: README.md
+Extra-Source-Files:
+  README.md
+  CHANGELOG.md
 
 library
   exposed-modules:
diff --git a/src/Sound/Jammit/Base.hs b/src/Sound/Jammit/Base.hs
--- a/src/Sound/Jammit/Base.hs
+++ b/src/Sound/Jammit/Base.hs
@@ -1,7 +1,7 @@
 {- |
 Basic types and functions for dealing with Jammit song packages.
 -}
-{-# LANGUAGE CPP #-}
+{-# LANGUAGE CPP             #-}
 {-# LANGUAGE RecordWildCards #-}
 module Sound.Jammit.Base
 ( Instrument(..)
@@ -23,21 +23,22 @@
 , sheetWidth, sheetHeight
 ) where
 
+import           Control.Applicative                ((<|>))
+import           Control.Monad                      (filterM, forM, guard)
+import           Data.Char                          (toLower)
+import qualified Data.Map                           as Map
+import           Data.Maybe                         (fromMaybe)
+import           Sound.Jammit.Internal.PropertyList
+import qualified System.Directory                   as Dir
+import           System.Environment                 (lookupEnv)
+import           System.FilePath                    (dropTrailingPathSeparator,
+                                                     takeFileName, (</>))
+import qualified System.Info                        as Info
+
 #if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>))
+import           Control.Applicative                ((<$>))
 #endif
-import Control.Applicative ((<|>))
-import Control.Monad (filterM, guard, forM)
-import Data.Char (toLower)
-import Data.Maybe (fromMaybe)
-import System.Environment (lookupEnv)
-import qualified Data.Map as Map
-import qualified System.Directory as Dir
-import System.FilePath ((</>), takeFileName, dropTrailingPathSeparator)
-import qualified System.Info as Info
 
-import Sound.Jammit.Internal.PropertyList
-
 -- | The 'Enum' instance corresponds to the number used in the 'instrument'
 -- property, and the names (used by 'Show' and 'Read') are capitalized versions
 -- of those used in the 'skillLevel' property.
@@ -236,7 +237,8 @@
 songSubdirs dir = case takeFileName $ dropTrailingPathSeparator dir of
   fn@('.' : _ : _) | fn /= ".." -> return []
   _                             -> do
-    isSong <- Dir.doesFileExist $ dir </> "info.plist"
+    isSong <- and <$> mapM Dir.doesFileExist
+      [dir </> "info.plist", dir </> "tracks.plist"]
     let here = [dir | isSong]
     subdirs <- lsAbsolute dir >>= filterM Dir.doesDirectoryExist
     (here ++) . concat <$> mapM songSubdirs subdirs
diff --git a/src/Sound/Jammit/Export.hs b/src/Sound/Jammit/Export.hs
--- a/src/Sound/Jammit/Export.hs
+++ b/src/Sound/Jammit/Export.hs
@@ -15,23 +15,21 @@
 , writeMetronomeTrack
 ) where
 
-import Control.Applicative (liftA2)
-import Control.Monad (forM, forever)
-import Data.Char (toLower)
-import Data.Int (Int16, Int32)
-import Data.List (isInfixOf, sort, isPrefixOf)
-import Data.Maybe (catMaybes)
-
-import System.Directory (getDirectoryContents)
-import System.FilePath ((</>), splitFileName, takeFileName)
-
-import Sound.Jammit.Internal.Image
-import Sound.Jammit.Base
-import Sound.Jammit.Internal.Audio
-import Sound.Jammit.Internal.TempIO
-
-import qualified Data.Conduit.Audio as A
-import Control.Monad.Trans.Resource (MonadResource, runResourceT)
+import           Control.Applicative          (liftA2)
+import           Control.Monad                (forM, forever)
+import           Control.Monad.Trans.Resource (MonadResource, runResourceT)
+import           Data.Char                    (toLower)
+import qualified Data.Conduit.Audio           as A
+import           Data.Int                     (Int16, Int32)
+import           Data.List                    (isInfixOf, isPrefixOf, sort)
+import           Data.Maybe                   (catMaybes, fromMaybe)
+import           Sound.Jammit.Base
+import           Sound.Jammit.Internal.Audio
+import           Sound.Jammit.Internal.Image
+import           Sound.Jammit.Internal.TempIO
+import           System.Directory             (getDirectoryContents)
+import           System.FilePath              (splitFileName, takeFileName,
+                                               (</>))
 
 type Library = [(FilePath, Info, [Track])]
 
@@ -81,15 +79,18 @@
     _ -> []
 
 audioSource :: (MonadResource m) => FilePath -> IO (A.AudioSource m Int16)
-audioSource fp = if takeFileName fp `elem` [tttDrums, tttDrumsBack]
-  then fmap (A.padStart $ A.Frames 38) $ readIMA fp
-  else readIMA fp
-  -- I've only found one audio file where the instruments are not aligned:
-  -- the drums and drums backing track for Take the Time are 38 samples ahead
-  -- of the other instruments. So as a hack, we pad the front of them by 38
-  -- samples to line things up.
-  where tttDrums     = "793EAAE0-6761-44D7-9A9A-1FB451A2A438_jcfx"
-        tttDrumsBack = "37EE5AA5-4049-4CED-844A-D34F6B165F67_jcfx"
+audioSource fp = let
+  -- These are hacks that make one instrument line up with the rest of a song.
+  timingHacks =
+    -- Take the Time (Dream Theater)
+    [ ("793EAAE0-6761-44D7-9A9A-1FB451A2A438_jcfx", A.padStart $ A.Frames 38) -- Drums
+    , ("37EE5AA5-4049-4CED-844A-D34F6B165F67_jcfx", A.padStart $ A.Frames 38) -- Drums backing
+    -- Rockstar (Nickelback)
+    , ("FB9A99DB-C70C-47CB-B63F-A78F11AC05D5_jcfx", A.dropStart $ A.Frames 10) -- Vocal
+    , ("7998F9B7-8A97-49D0-A3A9-C001FDD1C1DC_jcfx", A.dropStart $ A.Frames 10) -- B Vocals
+    , ("C4C543A0-EB1F-4628-A401-C5860D675FA4_jcfx", A.dropStart $ A.Frames 10) -- Vocal backing
+    ]
+  in fromMaybe id (lookup (takeFileName fp) timingHacks) <$> readIMA fp
 
 runAudio
   :: [FilePath] -- ^ AIFCs to mix in normally
diff --git a/src/Sound/Jammit/Internal/Audio.hs b/src/Sound/Jammit/Internal/Audio.hs
--- a/src/Sound/Jammit/Internal/Audio.hs
+++ b/src/Sound/Jammit/Internal/Audio.hs
@@ -13,10 +13,12 @@
 
 import           Control.Monad                (liftM2, unless)
 import           Control.Monad.IO.Class       (liftIO)
+import           Control.Monad.Trans.Resource (MonadResource)
 import qualified Data.ByteString              as B
-import           Data.ByteString.Char8        () -- for IsString instance
+import           Data.ByteString.Char8        ()
 import qualified Data.ByteString.Unsafe       as B
 import qualified Data.Conduit                 as C
+import qualified Data.Conduit.Audio           as A
 import qualified Data.Conduit.List            as CL
 import qualified Data.Vector.Storable         as V
 import           Foreign                      (Int16, Int32, Ptr, Word16,
@@ -26,9 +28,6 @@
 import           GHC.IO.Handle                (HandlePosn (..))
 import qualified System.IO                    as IO
 import           System.IO.Unsafe             (unsafePerformIO)
-
-import           Control.Monad.Trans.Resource (MonadResource)
-import qualified Data.Conduit.Audio           as A
 
 parseChunk :: IO.Handle -> IO (B.ByteString, (HandlePosn, HandlePosn))
 parseChunk h = do
diff --git a/src/Sound/Jammit/Internal/Image.hs b/src/Sound/Jammit/Internal/Image.hs
--- a/src/Sound/Jammit/Internal/Image.hs
+++ b/src/Sound/Jammit/Internal/Image.hs
@@ -3,18 +3,17 @@
 , jpegsToPDF
 ) where
 
-import qualified Codec.Picture as P
-import Codec.Picture.Types (convertImage)
-import Control.Monad (forM_, replicateM)
-import Control.Monad.IO.Class (MonadIO)
-import Control.Monad.Trans.Class (lift)
-import qualified Graphics.PDF as PDF
-import qualified Data.ByteString.Lazy as BL
-import qualified Data.Conduit as C
-import Data.Maybe (catMaybes)
-import qualified Data.Vector.Storable as V
-
-import Sound.Jammit.Internal.TempIO
+import qualified Codec.Picture                as P
+import           Codec.Picture.Types          (convertImage)
+import           Control.Monad                (forM_, replicateM)
+import           Control.Monad.IO.Class       (MonadIO)
+import           Control.Monad.Trans.Class    (lift)
+import qualified Data.ByteString.Lazy         as BL
+import qualified Data.Conduit                 as C
+import           Data.Maybe                   (catMaybes)
+import qualified Data.Vector.Storable         as V
+import qualified Graphics.PDF                 as PDF
+import           Sound.Jammit.Internal.TempIO
 
 loadPNG :: FilePath -> IO (P.Image P.PixelRGB8)
 loadPNG fp = do
diff --git a/src/Sound/Jammit/Internal/PropertyList.hs b/src/Sound/Jammit/Internal/PropertyList.hs
--- a/src/Sound/Jammit/Internal/PropertyList.hs
+++ b/src/Sound/Jammit/Internal/PropertyList.hs
@@ -1,8 +1,8 @@
 -- | A very simple, non-robust property list parser.
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE LambdaCase        #-}
+{-# LANGUAGE RecordWildCards   #-}
 module Sound.Jammit.Internal.PropertyList
 ( readPropertyList
 , PropertyList(..)
@@ -11,18 +11,18 @@
 , fromLookup
 ) where
 
-import qualified Data.Text.IO as TIO
-import Text.XML.Light
-import qualified Data.Map as Map
-import Text.Read (readMaybe)
-import Data.Maybe (mapMaybe, fromJust)
-import Data.Char (isSpace)
-import Control.Monad (guard)
+import           Control.Monad       (guard)
+import           Data.Char           (isSpace)
+import qualified Data.Map            as Map
+import           Data.Maybe          (fromJust, mapMaybe)
+import qualified Data.Text.IO        as TIO
+import           Text.Read           (readMaybe)
+import           Text.XML.Light
 
 #if !MIN_VERSION_base(4,8,0)
-import Prelude hiding (mapM)
-import Data.Traversable (mapM)
-import Control.Applicative ((<$>))
+import           Control.Applicative ((<$>))
+import           Data.Traversable    (mapM)
+import           Prelude             hiding (mapM)
 #endif
 
 data PropertyList
diff --git a/src/Sound/Jammit/Internal/TempIO.hs b/src/Sound/Jammit/Internal/TempIO.hs
--- a/src/Sound/Jammit/Internal/TempIO.hs
+++ b/src/Sound/Jammit/Internal/TempIO.hs
@@ -8,15 +8,15 @@
 , liftIO
 ) where
 
-import Data.List (stripPrefix)
-import System.IO (hClose)
-import System.IO.Error (catchIOError)
-
-import Control.Monad.IO.Class (liftIO)
-import Control.Monad.Trans.Reader (ask, ReaderT(..))
-import System.Directory (copyFile, renameFile)
-import System.FilePath (splitPath)
-import System.IO.Temp (openTempFile, withSystemTempDirectory)
+import           Control.Monad.IO.Class     (liftIO)
+import           Control.Monad.Trans.Reader (ReaderT (..), ask)
+import           Data.List                  (stripPrefix)
+import           System.Directory           (copyFile, renameFile)
+import           System.FilePath            (splitPath)
+import           System.IO                  (hClose)
+import           System.IO.Error            (catchIOError)
+import           System.IO.Temp             (openTempFile,
+                                             withSystemTempDirectory)
 
 -- | A wrapper around IO with a designated directory for temporary files.
 type TempIO = ReaderT FilePath IO
