module Synthesizer.LLVM.Server.SampledSound where
import Synthesizer.LLVM.Server.Common (Real)
import qualified Sound.Sox.Read as SoxRead
import qualified Sound.Sox.Option.Format as SoxOption
import Control.Exception (bracket)
import qualified Synthesizer.Storable.Signal as SigSt
import qualified Data.StorableVector.Lazy as SVL
import qualified System.Path.PartClass as PathClass
import qualified System.Path as Path
import System.Path ((</>))
import Data.Tuple.HT (mapPair)
import qualified Number.DimensionTerm as DN
import Prelude hiding (Real, length)
data T =
Cons {
body :: SigSt.T Real,
sampleRate :: DN.Frequency Real,
positions :: Positions
}
data Positions =
Positions {
start, length,
loopStart, loopLength :: Int,
period :: Real
}
load :: (PathClass.AbsRel ar) => Path.File ar -> IO (SVL.Vector Real)
load path =
bracket (SoxRead.open SoxOption.none (Path.toString path)) SoxRead.close $
SoxRead.withHandle1 (SVL.hGetContentsSync SVL.defaultChunkSize)
loadRanges :: (PathClass.AbsRel ar) => Path.Dir ar -> Info -> IO [T]
loadRanges dir (Info file sr poss) =
fmap
(\smp -> map (Cons smp (DN.frequency sr)) poss)
(load (dir </> file))
data
Info =
Info {
infoName :: Path.RelFile,
infoRate :: Real,
infoPositions :: [Positions]
}
info :: FilePath -> Real -> [Positions] -> Info
info path = Info (Path.relFile path)
parts :: T -> (SigSt.T Real, SigSt.T Real, SigSt.T Real)
parts smp =
let pos = positions smp
(attack,sustain) =
mapPair
(SigSt.drop (start pos),
SigSt.take (loopLength pos)) $
SigSt.splitAt (loopStart pos) $
body smp
release =
SigSt.drop (loopStart pos + loopLength pos) $
SigSt.take (start pos + length pos) $
body smp
in (attack, sustain, release)
tomatensalatPositions :: [Positions]
tomatensalatPositions =
Positions 0 29499 12501 15073 321.4 :
Positions 29499 31672 38163 17312 320.6 :
Positions 67379 28610 81811 10667 323.2 :
Positions 95989 31253 106058 16111 323.7 :
Positions 127242 38596 136689 11514 319.3 :
[]
tomatensalat :: Info
tomatensalat =
info "tomatensalat2.wav" 44100 tomatensalatPositions
halPositions :: [Positions]
halPositions =
Positions 2371 25957 (2371+25957) 1 320 :
Positions 40546 34460 63540 9546 317.4 :
Positions 79128 32348 94367 14016 317.8 :
Positions 112027 21227 125880 5500 322.5 :
Positions 146057 23235 168941 352 320 :
[]
hal :: Info
hal =
info "haskell-in-leipzig2.wav" 44100 halPositions
graphentheoriePositions :: [Positions]
graphentheoriePositions =
Positions 0 29524 13267 14768 301.1 :
Positions 29524 35333 47624 9968 301.6 :
Positions 64857 31189 73818 16408 297.3 :
Positions 96046 31312 106206 18504 302.9 :
Positions 127358 32127 132469 16530 299.4 :
[]
graphentheorie :: Info
graphentheorie =
info "graphentheorie0.wav" 44100 graphentheoriePositions