packages feed

hsc3-auditor-0.11: Sound/SC3/Auditor/TR808.hs

-- | /TR808/ sample library based auditioner.
module Sound.SC3.Auditor.TR808 where

import Data.List
import Data.Maybe
import Sound.OpenSoundControl {- hosc -}
import Sound.SC3 {- hsc3 -}
import Sound.SC3.Auditor
import System.FilePath {- filepath -}

-- | Enumeration of TR808 instruments.
data TR808 = BD | SD
           | LT' | MT | HT
           | LC | MC | HC
           | RS | CL | CP | MA | CB
           | CY | OH | CH
             deriving (Eq,Ord,Enum,Bounded,Show)

-- | Controller positions to index sample library.
data POSITION = P0 | P1 | P2 | P3 | P4
                deriving (Eq,Ord,Enum,Bounded,Show)

-- | Set of relevant 'POSITION' data.
type PARAMETERS = [POSITION]

-- | Translate 'POSITION' to 'String' encoding in file names.
position_text :: POSITION -> String
position_text i =
    case i of
      P0 -> "00"
      P1 -> "25"
      P2 -> "50"
      P3 -> "75"
      P4 -> "10"

-- | Function to give number of parameters for each 'TR808' instrument.
tr808_n_param :: TR808 -> Int
tr808_n_param i =
    case i of
      BD -> 2
      CB -> 0
      CH -> 0
      CL -> 0
      CP -> 0
      CY -> 2
      HC -> 1
      HT -> 1
      LC -> 1
      LT' -> 1
      MA -> 0
      MC -> 1
      MT -> 1
      OH -> 1
      RS -> 0
      SD -> 2

-- | Prettty printer variant of 'Show' instance for 'TR808'.
tr808_abbrev :: TR808 -> String
tr808_abbrev i =
    case i of
      LT' -> "LT"
      _ -> show i

-- | 'TR808' instrument names.
tr808_name :: TR808 -> String
tr808_name i =
    case i of
      BD -> "BASS DRUM"
      CB -> "COW BELL"
      CH -> "CLOSED HI HAT"
      CL -> "CLAVES"
      CP -> "HAND CLAP"
      CY -> "CYMBAL"
      HC -> "HIGH CONGA"
      HT -> "HIGH TOM"
      LC -> "LOW CONGA"
      LT' -> "LOW TOM"
      MA -> "MARACAS"
      MC -> "MID CONGA"
      MT -> "MID TOM"
      OH -> "OPEN HI HAT"
      RS -> "RIM SHOT"
      SD -> "SNARE DRUM"

-- | Generate 'FilePath' for 'TR808' instrument with indicated 'PARAMETERS'.
tr808_file_name :: TR808 -> PARAMETERS -> FilePath
tr808_file_name i ps =
    let i' = tr808_abbrev i </> tr808_abbrev i
        ps' = concatMap position_text ps
    in i' ++ ps' <.> "WAV"

-- | Generate full set of 'FilePath' for all 'POSITION's of 'TR808'.
tr808_file_names :: TR808 -> [FilePath]
tr808_file_names i =
    let pp = [minBound .. maxBound]
        f = map (tr808_file_name i)
    in case tr808_n_param i of
         0 -> [tr808_file_name i []]
         1 -> f [[j] | j <- pp]
         2 -> f [[j,k] | j <- pp, k <- pp]
         _ -> error "tr808_file_names"

-- | The complete set of 'TR808' sample 'FilePath's.
tr808_file_map :: [FilePath]
tr808_file_map = concatMap tr808_file_names [minBound .. maxBound]

-- | The set of all 'TR808' data.
tr808_u :: [(TR808,PARAMETERS)]
tr808_u =
    let ts = [minBound .. maxBound]
        ps = [minBound .. maxBound]
        f t = case tr808_n_param t of
                0 -> [(t,[])]
                1 -> [(t,[p]) | p <- ps]
                2 -> [(t,[p0,p1]) | p0 <- ps, p1 <- ps]
                _ -> error "tr808_u"
    in concatMap f ts

-- | Lookup 'INDEX' for 'TR808' at indicated 'PARAMETERS'.
tr808_index :: TR808 -> PARAMETERS -> INDEX
tr808_index i ps =
    let nm = tr808_file_name i ps
        err = error "tr808_index"
    in fromMaybe err (findIndex (== nm) tr808_file_map)

-- | Buffer /allocate and read/ message for @scsynth@.
tr808_alloc_osc :: FilePath -> (FilePath,Int) -> OSC
tr808_alloc_osc d (fn,i) = b_allocRead i (d </> fn) 0 0

-- | Complete set of 'tr808_alloc_osc' messages for 'TR808'.
tr808_alloc_all_osc :: FilePath -> [OSC]
tr808_alloc_all_osc d = map (tr808_alloc_osc d) (zip tr808_file_map [0..])

-- | Variant of 'tr808_alloc_all_osc' to load required subset of library.
tr808_alloc_subset_osc :: FilePath -> SAMPLE_LOADER
tr808_alloc_subset_osc d ix =
    let nm = filter ((`elem` ix) . snd) (zip tr808_file_map [0..])
    in map (tr808_alloc_osc d) nm

-- | Send 'OSC' set given by 'tr808_alloc_all_osc' to @scsynth@ at
-- 'Transport'.
au_load_tr808_set :: Transport t => FilePath -> t -> IO ()
au_load_tr808_set d fd = mapM_ (async fd) (tr808_alloc_all_osc d)

{-
let d = "/home/rohan/disk/proudhon/data/tr-808"
tr808_alloc_all_osc d
let f = tr808_index in tr808_alloc_subset_osc d [f RS [],f CL [],f CH []]
-}