packages feed

audacity 0.0.1.2 → 0.0.1.3

raw patch · 3 files changed

+107/−4 lines, 3 filesdep ~basedep ~directorydep ~non-emptynew-component:exe:sox-splitPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, directory, non-empty, storablevector, utility-ht

API changes (from Hackage documentation)

Files

audacity.cabal view
@@ -1,5 +1,5 @@ Name:                audacity-Version:             0.0.1.2+Version:             0.0.1.3 Synopsis:            Interchange with the Audacity sound signal editor Description:   This package provides functions@@ -10,6 +10,12 @@   .   We provide some examples that are useful on its own:   .+  * @sox-split@:+    Split an audio file according to a label track.+    Audacity provides this function by itself.+    You can use placeholders like @%s@ and @%02d@+    in order to compose the names of the parts from the labels and positions.+  .   * @sox-concat@:     Concatenate a sequence of sound files with matching     sampling rates and numbers of channels using SoX@@ -35,7 +41,7 @@ Cabal-Version:       >=1.10  Source-Repository this-  Tag:         0.0.1.2+  Tag:         0.0.1.3   Type:        darcs   Location:    http://hub.darcs.net/thielema/audacity @@ -75,6 +81,26 @@   Hs-Source-Dirs:      src   Default-Language:    Haskell2010   GHC-Options:         -Wall++Executable sox-split+  Main-Is:             Split.hs+  Other-Modules:       Common+  Hs-Source-Dirs:      example+  Default-Language:    Haskell2010+  GHC-Options:         -Wall+  If flag(buildExamples)+    Build-Depends:+      audacity,+      soxlib >=0.0 && <0.1,+      storablevector,+      directory,+      optparse-applicative >=0.11 && <0.15,+      filepath >=1.3 && <1.5,+      non-empty,+      utility-ht,+      base+  Else+    Buildable: False  Executable sox-concat   Main-Is:             Concatenate.hs
example/Common.hs view
@@ -80,7 +80,7 @@ some :: OP.Parser a -> OP.Parser (NonEmpty.T [] a) some p = OPInt.fromM $ OP.liftA2 (!:) (OPInt.oneM p) (OPInt.manyM p) -parseArgs :: OP.Parser (NonEmpty.T [] String, String)+parseArgs :: OP.Parser (NonEmpty.T [] FilePath, FilePath) parseArgs =    OP.liftA2 (,)       (some (OP.strArgument (OP.metavar "SRC")))@@ -92,5 +92,5 @@       (OP.helper <*> parser)       (OP.fullDesc <> OP.progDesc desc) -multiArgs :: String -> IO (NonEmpty.T [] String, String)+multiArgs :: String -> IO (NonEmpty.T [] FilePath, FilePath) multiArgs desc = OP.execParser $ info desc parseArgs
+ example/Split.hs view
@@ -0,0 +1,77 @@+module Main where++import Common (defaultSampleRate, info, withSound, writerInfoFromFormat)++import qualified Sound.Audacity.LabelTrack as LabelTrack+import qualified Sound.SoxLib as SoxLib++import qualified Data.StorableVector.Lazy as SVL++import qualified Options.Applicative as OP+import Control.Monad (forM_)++import qualified Data.List as List+import Data.Maybe (fromMaybe)+import Data.Monoid ((<>))+import Data.Tuple.HT (uncurry3)+import Data.Ord.HT (comparing)+import Data.Char (isDigit)+import Data.Int (Int32)++import Text.Printf (printf)+++formatName :: String -> Int -> String -> String+formatName fmt k label =+   let go ('%':cs0) =+         case cs0 of+            's':cs1 -> label ++ go cs1+            '%':cs1 -> '%' : go cs1+            _ ->+               case span isDigit cs0 of+                  (digits,'d':cs2) -> printf ("%"++digits++"d") k ++ go cs2+                  _ -> '%' : go cs0+       go (c:cs) = c : go cs+       go [] = []+   in  go fmt++split ::+   LabelTrack.T Int a -> Int -> SVL.Vector Int32 ->+   [(a, SVL.Vector Int32)]+split labels numChan sig =+   snd $+   List.mapAccumL+      (\(tOld,sigOld) ((t0,t1),label) ->+         let sigNew = SVL.drop (numChan*(t0-tOld)) sigOld+         in  ((t0,sigNew), (label, SVL.take (numChan*(t1-t0)) sigNew)))+      (0, sig) $+   List.sortBy (comparing fst) $ LabelTrack.decons labels++run :: FilePath -> FilePath -> FilePath -> IO ()+run labelFile input output = do+   labels <- LabelTrack.readFile labelFile+   withSound input $ \fmtIn mrate numChan sig -> do+      let rate = fromMaybe defaultSampleRate mrate+          pieces =+            split (LabelTrack.mapTime (\t -> round (t*rate)) labels) numChan sig+      forM_ (zip [0..] pieces) $ \(k,(label,piece)) ->+         SoxLib.withWrite+            (writerInfoFromFormat fmtIn)+            (formatName output k label)+            (flip SoxLib.writeStorableVectorLazy piece)++parseArgs :: OP.Parser (FilePath, FilePath, FilePath)+parseArgs =+   OP.liftA3 (,,)+      (OP.strArgument (OP.metavar "LABELTRACK"))+      (OP.strArgument (OP.metavar "INPUT"))+      (OP.strOption+         (OP.long "output" <> OP.metavar "FMT" <> OP.value "%s.wav"+            <> OP.help "include %s for labels and %03d for counts"))++main :: IO ()+main =+   SoxLib.formatWith $+   uncurry3 run =<<+      OP.execParser+         (info "Split audio file according to label track" parseArgs)