-- | Rather ad-hoc accumulation of meta-data about SC3 UGens. module Sound.SC3.UGen.DB.Meta where import Data.List {- base -} import Data.Maybe {- base -} import Sound.SC3.UGen.Rate {- hsc3 -} -- | Meta data not gleamed from sclang. data Meta = Meta {m_name :: String ,m_nc_input :: Bool -- ^ Number of output channels is given as psuedo input. ,m_nc_mce :: Maybe Int -- ^ Number of output channels is given by degree of MCE input plus indicated offset. ,m_input_reorder :: Maybe [Int] -- ^ SC3 reordering, pseudo (ie. NC) inputs at sclang ugens aren't mentioned here. ,m_std_mce :: Bool -- ^ UGens that have an MCE input as the last input. ,m_secondary_mce :: Maybe Int -- ^ Secondary, length pre-fixed MCE input. ,m_enumerations :: Maybe [(Int,String)] -- ^ Enumerated (not plain) inputs. -- Indices are /UGen/ indices, not /sclang/ indices. ,m_filter :: Maybe [Int] -- ^ Rate is given by rate of indicated inputs. -- Indices are /UGen/ indices, not /sclang/ indices. ,m_fixed_rate :: Maybe Rate -- ^ Operate only at one fixed rate, which can be elided. ,m_nondet :: Bool -- ^ Required distinguishing identifier for (in-)equality. ,m_pseudo_inputs :: Maybe [Int] -- ^ SC3 binding includes a pseudo input (not NC). ,m_i_rate :: Bool -- ^ Operates at i-rate despite not having .ir method. } deriving Show -- | Default (empty) meta data. def_meta :: String -> Meta def_meta nm = let n = Nothing f = False in Meta nm f n n f n n n n f n f -- | Encoding of 'Meta'. meta_data :: [Meta] meta_data = [(def_meta "A2K") {m_fixed_rate = Just KR} ,(def_meta "APF") {m_filter = Just [0]} ,(def_meta "AllpassC") {m_filter = Just [0]} ,(def_meta "AllpassL") {m_filter = Just [0]} ,(def_meta "AllpassN") {m_filter = Just [0]} ,(def_meta "BAllPass") {m_filter = Just [0]} ,(def_meta "BBandPass") {m_filter = Just [0]} ,(def_meta "BBandStop") {m_filter = Just [0]} ,(def_meta "BHiPass") {m_filter = Just [0]} ,(def_meta "BHiShelf") {m_filter = Just [0]} ,(def_meta "BlockSize") {m_fixed_rate = Just IR} ,(def_meta "BLowPass") {m_filter = Just [0]} ,(def_meta "BLowShelf") {m_filter = Just [0]} ,(def_meta "BPF") {m_filter = Just [0]} ,(def_meta "BPZ2") {m_filter = Just [0]} ,(def_meta "BPeakEQ") {m_filter = Just [0]} ,(def_meta "BRF") {m_filter = Just [0]} ,(def_meta "BRZ2") {m_filter = Just [0]} ,(def_meta "BinaryOpUGen") {m_filter = Just [0,1]} ,(def_meta "BrownNoise") {m_nondet = True} ,(def_meta "BufRd") {m_nc_input = True,m_enumerations = Just [(2,"Loop"),(3,"Interpolation")]} ,(def_meta "BufWr") {m_filter = Just [3],m_enumerations = Just [(2,"Loop")],m_std_mce = True,m_input_reorder = Just [3,0,1,2]} ,(def_meta "CheckBadValues") {m_filter = Just [0]} ,(def_meta "Clip") {m_filter = Just [0]} ,(def_meta "ClipNoise") {m_nondet = True} ,(def_meta "CoinGate") {m_filter = Just [1],m_nondet = True} ,(def_meta "CombC") {m_filter = Just [0]} ,(def_meta "CombL") {m_filter = Just [0]} ,(def_meta "CombN") {m_filter = Just [0]} ,(def_meta "Compander") {m_filter = Just [0]} ,(def_meta "ComplexRes") {m_filter = Just [0]} ,(def_meta "ControlDur") {m_fixed_rate = Just IR} ,(def_meta "ControlRate") {m_fixed_rate = Just IR} ,(def_meta "Dbrown") {m_input_reorder = Just [1,2,3,0]} ,(def_meta "Dbufrd") {m_enumerations = Just [(2,"Loop")]} ,(def_meta "Dbufwr") {m_enumerations = Just [(3,"Loop")],m_input_reorder = Just [3,0,1,2]} ,(def_meta "Decay") {m_filter = Just [0]} ,(def_meta "Decay2") {m_filter = Just [0]} ,(def_meta "DecodeB2") {m_nc_input = True} ,(def_meta "DegreeToKey") {m_filter = Just [1]} ,(def_meta "Delay1") {m_filter = Just [0]} ,(def_meta "Delay2") {m_filter = Just [0]} ,(def_meta "DelayC") {m_filter = Just [0]} ,(def_meta "DelayL") {m_filter = Just [0]} ,(def_meta "DelayN") {m_filter = Just [0]} ,(def_meta "DelTapRd") {m_filter = Just [1]} ,(def_meta "DelTapWr") {m_filter = Just [1]} ,(def_meta "Demand") {m_filter = Just [0],m_std_mce = True,m_nc_mce = Just 0} ,(def_meta "DemandEnvGen") {m_enumerations = Just [(9,"DoneAction")]} ,(def_meta "DetectIndex") {m_filter = Just [1]} ,(def_meta "DetectSilence") {m_enumerations = Just [(3,"DoneAction")],m_filter = Just [0]} ,(def_meta "Dgeom") {m_input_reorder = Just [1,2,0]} ,(def_meta "Dibrown") {m_input_reorder = Just [1,2,3,0]} ,(def_meta "DiodeRingMod") {m_filter = Just [0]} ,(def_meta "DiskIn") {m_enumerations = Just [(1,"Loop")],m_nc_input = True,m_fixed_rate = Just AR} ,(def_meta "DiskOut") {m_fixed_rate = Just AR,m_std_mce = True} ,(def_meta "Diwhite") {m_input_reorder = Just [1,2,0]} ,(def_meta "Drand") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dseq") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dser") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dseries") {m_input_reorder = Just [1,2,0]} ,(def_meta "Dshuf") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dswitch") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dswitch1") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "Dust") {m_nondet = True} ,(def_meta "Dust2") {m_nondet = True} ,(def_meta "Duty") {m_enumerations = Just [(2,"DoneAction")],m_input_reorder = Just [0,1,3,2]} ,(def_meta "Dwhite") {m_input_reorder = Just [1,2,0]} ,(def_meta "Dwrand") {m_secondary_mce = Just 1,m_std_mce = True,m_input_reorder = Just [2,1,0]} ,(def_meta "Dxrand") {m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "EnvGen") {m_enumerations = Just [(4,"DoneAction"),(5,"Envelope UGen")],m_std_mce = True,m_input_reorder = Just [5,0,1,2,3,4,5]} ,(def_meta "ExpRand") {m_filter = Just [0,1],m_fixed_rate = Just IR,m_nondet = True} ,(def_meta "FFT") {m_fixed_rate = Just KR} ,(def_meta "FOS") {m_filter = Just [0]} ,(def_meta "Fold") {m_filter = Just [0]} ,(def_meta "Formlet") {m_filter = Just [0]} ,(def_meta "Free") {m_filter = Just [0],m_fixed_rate = Just KR} ,(def_meta "FreeSelf") {m_fixed_rate = Just KR} ,(def_meta "FreeVerb") {m_filter = Just [0]} ,(def_meta "FreeVerb2") {m_filter = Just [0]} ,(def_meta "FreqShift") {m_fixed_rate = Just AR} ,(def_meta "GVerb") {m_filter = Just [0]} ,(def_meta "Gate") {m_filter = Just [0]} ,(def_meta "Gendy1") {m_nondet = True} ,(def_meta "Gendy2") {m_nondet = True} ,(def_meta "Gendy3") {m_nondet = True} ,(def_meta "GrainBuf") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "GrainFM") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "GrainIn") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "GrainSin") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "GrayNoise") {m_nondet = True} ,(def_meta "Greyhole") {m_filter = Just [0]} ,(def_meta "HPF") {m_filter = Just [0]} ,(def_meta "HPZ1") {m_filter = Just [0]} ,(def_meta "HPZ2") {m_filter = Just [0]} ,(def_meta "Hasher") {m_filter = Just [0]} ,(def_meta "Hilbert") {m_filter = Just [0]} ,(def_meta "IEnvGen") {m_enumerations = Just [(1,"Envelope UGen")],m_std_mce = True,m_input_reorder = Just [1,0]} ,(def_meta "IFFT") {m_fixed_rate = Just AR} ,(def_meta "IRand") {m_fixed_rate = Just IR,m_nondet = True} ,(def_meta "In") {m_nc_input = True} ,(def_meta "InFeedback") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "InRange") {m_filter = Just [0]} ,(def_meta "InTrig") {m_nc_input = True} ,(def_meta "Index") {m_filter = Just [1]} ,(def_meta "Integrator") {m_filter = Just [0]} ,(def_meta "JPverbRaw") {m_filter = Just [0]} ,(def_meta "K2A") {m_fixed_rate = Just AR} ,(def_meta "Klang") {m_std_mce = True,m_input_reorder = Just [2,0,1]} ,(def_meta "Klank") {m_filter = Just [0],m_std_mce = True,m_input_reorder = Just [4,0,1,2,3]} ,(def_meta "LFClipNoise") {m_nondet = True} ,(def_meta "LFDClipNoise") {m_nondet = True} ,(def_meta "LFDNoise0") {m_nondet = True} ,(def_meta "LFDNoise1") {m_nondet = True} ,(def_meta "LFDNoise3") {m_nondet = True} ,(def_meta "LFGauss") {m_enumerations = Just [(3,"Loop"),(4,"DoneAction")]} ,(def_meta "LFNoise0") {m_nondet = True} ,(def_meta "LFNoise1") {m_nondet = True} ,(def_meta "LFNoise2") {m_nondet = True} ,(def_meta "LPF") {m_filter = Just [0]} ,(def_meta "LPZ1") {m_filter = Just [0]} ,(def_meta "LPZ2") {m_filter = Just [0]} ,(def_meta "Lag") {m_filter = Just [0]} ,(def_meta "Lag2") {m_filter = Just [0]} ,(def_meta "Lag2UD") {m_filter = Just [0]} ,(def_meta "Lag3") {m_filter = Just [0]} ,(def_meta "Lag3UD") {m_filter = Just [0]} ,(def_meta "LagIn") {m_nc_input = True,m_fixed_rate = Just KR} ,(def_meta "LagUD") {m_filter = Just [0]} ,(def_meta "LastValue") {m_filter = Just [0]} ,(def_meta "Latch") {m_filter = Just [0]} ,(def_meta "LeakDC") {m_filter = Just [0]} ,(def_meta "Limiter") {m_filter = Just [0]} ,(def_meta "LinExp") {m_filter = Just [0]} ,(def_meta "LinPan2") {m_filter = Just [0]} ,(def_meta "LinRand") {m_fixed_rate = Just IR,m_nondet = True} ,(def_meta "LinXFade2") {m_filter = Just [0,1],m_pseudo_inputs = Just [3]} ,(def_meta "Line") {m_enumerations = Just [(3,"DoneAction")]} ,(def_meta "Linen") {m_enumerations = Just [(4,"DoneAction")],m_fixed_rate = Just KR} ,(def_meta "LocalBuf") {m_fixed_rate = Just IR,m_input_reorder = Just [1,0],m_nondet = True} ,(def_meta "LocalIn") {m_nc_input = True,m_std_mce = True} ,(def_meta "LocalOut") {m_filter = Just [0],m_std_mce = True} ,(def_meta "LoopBuf") {m_nc_input = True} ,(def_meta "MantissaMask") {m_filter = Just [0]} ,(def_meta "Median") {m_filter = Just [1]} ,(def_meta "MidEQ") {m_filter = Just [0]} ,(def_meta "MoogFF") {m_filter = Just [0]} ,(def_meta "MostChange") {m_filter = Just [0,1]} ,(def_meta "MouseX") {m_enumerations = Just [(2,"Warp")]} ,(def_meta "MouseY") {m_enumerations = Just [(2,"Warp")]} ,(def_meta "MulAdd") {m_filter = Just [0]} ,(def_meta "NRand") {m_fixed_rate = Just IR,m_nondet = True} ,(def_meta "Normalizer") {m_filter = Just [0]} ,(def_meta "NumAudioBuses") {m_fixed_rate = Just IR} ,(def_meta "NumBuffers") {m_fixed_rate = Just IR} ,(def_meta "NumControlBuses") {m_fixed_rate = Just IR} ,(def_meta "NumInputBuses") {m_fixed_rate = Just IR} ,(def_meta "NumOutputBuses") {m_fixed_rate = Just IR} ,(def_meta "NumRunningSynths") {m_fixed_rate = Just IR} ,(def_meta "OffsetOut") {m_filter = Just [1],m_std_mce = True} ,(def_meta "OnePole") {m_filter = Just [0]} ,(def_meta "OneZero") {m_filter = Just [0]} ,(def_meta "Onsets") {m_fixed_rate = Just KR} ,(def_meta "Out") {m_filter = Just [1],m_std_mce = True} ,(def_meta "PV_BinScramble") {m_nondet = True} ,(def_meta "PV_RandComb") {m_nondet = True} ,(def_meta "PV_RandWipe") {m_nondet = True} ,(def_meta "PV_Split") {m_fixed_rate = Just KR} ,(def_meta "PackFFT") {m_std_mce = True,m_input_reorder = Just [0,1,6,2,3,4]} -- 5: implicit ,(def_meta "Pan2") {m_filter = Just [0]} ,(def_meta "PanAz") {m_filter = Just [0],m_nc_input = True} ,(def_meta "PartConv") {m_fixed_rate = Just AR} ,(def_meta "Peak") {m_filter = Just [0]} ,(def_meta "PeakFollower") {m_filter = Just [0]} ,(def_meta "PinkNoise") {m_nondet = True} ,(def_meta "Pitch") {m_fixed_rate = Just KR} ,(def_meta "PitchShift") {m_filter = Just [0]} ,(def_meta "PlayBuf") {m_enumerations = Just [(4,"Loop"),(5,"DoneAction")],m_nc_input = True} ,(def_meta "Pluck") {m_filter = Just [0]} ,(def_meta "Poll") {m_filter = Just [1]} ,(def_meta "PulseCount") {m_filter = Just [0]} ,(def_meta "PulseDivider") {m_filter = Just [0]} ,(def_meta "RHPF") {m_filter = Just [0]} ,(def_meta "RLPF") {m_filter = Just [0]} ,(def_meta "RShufflerB") {m_fixed_rate = Just AR} ,(def_meta "RadiansPerSample") {m_fixed_rate = Just IR} ,(def_meta "Ramp") {m_filter = Just [0]} ,(def_meta "Rand") {m_fixed_rate = Just IR,m_nondet = True} ,(def_meta "RecordBuf") {m_enumerations = Just [(5,"Loop"),(7,"DoneAction")],m_std_mce = True,m_input_reorder = Just [8,0,1,2,3,4,5,6,7]} ,(def_meta "ReplaceOut") {m_filter = Just [1],m_std_mce = True} ,(def_meta "Resonz") {m_filter = Just [0]} ,(def_meta "Ringz") {m_filter = Just [0]} ,(def_meta "Rotate2") {m_filter = Just [0,1]} ,(def_meta "RunningMax") {m_filter = Just [0]} ,(def_meta "RunningMin") {m_filter = Just [0]} ,(def_meta "RunningSum") {m_filter = Just [0]} ,(def_meta "SOS") {m_filter = Just [0]} ,(def_meta "SampleDur") {m_fixed_rate = Just IR} ,(def_meta "SampleRate") {m_fixed_rate = Just IR} ,(def_meta "Select") {m_filter = Just [0,1],m_std_mce = True,m_i_rate = True} ,(def_meta "SendReply") {m_filter = Just [0]} ,(def_meta "SendTrig") {m_filter = Just [0]} ,(def_meta "SetBuf") {m_fixed_rate = Just IR,m_std_mce = True,m_input_reorder = Just [0,1,2,3]} -- local def. ,(def_meta "SetResetFF") {m_filter = Just [0]} ,(def_meta "Shaper") {m_filter = Just [1]} ,(def_meta "Slew") {m_filter = Just [0]} ,(def_meta "Slope") {m_filter = Just [0]} ,(def_meta "Stepper") {m_filter = Just [0]} ,(def_meta "SubsampleOffset") {m_fixed_rate = Just IR} ,(def_meta "Sum3") {m_filter = Just [0,1,2]} ,(def_meta "Sum4") {m_filter = Just [0,1,2,3]} ,(def_meta "Sweep") {m_filter = Just [0]} ,(def_meta "T2A") {m_fixed_rate = Just AR} ,(def_meta "TChoose") {m_nondet = True} ,(def_meta "TDelay") {m_filter = Just [0]} ,(def_meta "TDuty") {m_enumerations = Just [(2,"DoneAction")],m_input_reorder = Just [0,1,3,2,4]} ,(def_meta "TExpRand") {m_filter = Just [2],m_nondet = True} ,(def_meta "TGrains") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "TGrains2") {m_nc_input = True} ,(def_meta "TGrains3") {m_nc_input = True} ,(def_meta "TIRand") {m_filter = Just [2],m_nondet = True} ,(def_meta "TRand") {m_filter = Just [2],m_nondet = True} ,(def_meta "TWChoose") {m_nondet = True} ,(def_meta "TWindex") {m_filter = Just [0],m_nondet = True,m_std_mce = True,m_input_reorder = Just [0,2,1]} ,(def_meta "Tap") {m_nc_input = True} ,(def_meta "Timer") {m_filter = Just [0]} ,(def_meta "ToggleFF") {m_filter = Just [0]} ,(def_meta "Trig") {m_filter = Just [0]} ,(def_meta "Trig1") {m_filter = Just [0]} ,(def_meta "TwoPole") {m_filter = Just [0]} ,(def_meta "TwoZero") {m_filter = Just [0]} ,(def_meta "UnaryOpUGen") {m_filter = Just [0]} ,(def_meta "VBAP") {m_nc_input = True} ,(def_meta "VDiskIn") {m_enumerations = Just [(2,"Loop")],m_nc_input = True,m_fixed_rate = Just AR} ,(def_meta "Vibrato") {m_nondet = True} ,(def_meta "Warp1") {m_fixed_rate = Just AR,m_nc_input = True} ,(def_meta "WarpZ") {m_nc_input = True} ,(def_meta "WhiteNoise") {m_nondet = True} ,(def_meta "Wrap") {m_filter = Just [0]} ,(def_meta "WrapIndex") {m_filter = Just [1]} ,(def_meta "XFade2") {m_filter = Just [0,1]} ,(def_meta "XLine") {m_enumerations = Just [(3,"DoneAction")]} ,(def_meta "XOut") {m_filter = Just [2],m_std_mce = True} ,(def_meta "ZeroCrossing") {m_filter = Just [0]} ] -- * Derived (historical) lists. -- | Extract set of (name,value) pairs give field function. meta_zip_just :: (Meta -> Maybe t) -> [(String,t)] meta_zip_just fld = let f m = case fld m of {Just r -> Just (m_name m,r); Nothing -> Nothing} in mapMaybe f meta_data meta_nc_input :: [String] meta_nc_input = map m_name (filter m_nc_input meta_data) meta_nc_mce :: [(String,Int)] meta_nc_mce = meta_zip_just m_nc_mce meta_input_reorder :: [(String,[Int])] meta_input_reorder = meta_zip_just m_input_reorder meta_std_mce :: [String] meta_std_mce = map m_name (filter m_std_mce meta_data) meta_secondary_mce :: [(String,Int)] meta_secondary_mce = meta_zip_just m_secondary_mce meta_enumeration_inputs :: [(String,[(Int,String)])] meta_enumeration_inputs = meta_zip_just m_enumerations meta_filters :: [(String,[Int])] meta_filters = meta_zip_just m_filter meta_fixed_rate :: [(String,Rate)] meta_fixed_rate = meta_zip_just m_fixed_rate meta_nondet :: [String] meta_nondet = map m_name (filter m_nondet meta_data) -- | This is unnecessary, it's generated from 'u_is_demand_rate'. meta_demand :: [String] meta_demand = ["Dbrown","Dbufrd","Dbufwr","Dgeom","Dibrown","Diwhite","Donce","Dpoll","Drand","Dreset","Dseq","Dser","Dseries","Dshuf","Dstutter","Dswitch","Dswitch1","Dunique","Dwhite","Dwrand","Dxrand"] meta_pseudo_inputs :: [(String,[Int])] meta_pseudo_inputs = meta_zip_just m_pseudo_inputs -- * Predicates meta_has_nc_input :: String -> Bool meta_has_nc_input nm = nm `elem` meta_nc_input meta_has_var_inputs :: String -> Bool meta_has_var_inputs nm = meta_has_nc_input nm || nm `elem` (map fst meta_nc_mce) meta_is_filter :: String -> Bool meta_is_filter = isJust . flip lookup meta_filters meta_is_operator :: String -> Bool meta_is_operator = flip elem ["UnaryOpUGen","BinaryOpUGen"] meta_is_nondet :: String -> Bool meta_is_nondet nm = nm `elem` meta_nondet || nm `elem` meta_demand -- | All of the PV_ are rate fixed meta_is_fixed_rate :: String -> Maybe Rate meta_is_fixed_rate nm = if nm `elem` meta_demand then Just DR else if "PV_" `isPrefixOf` nm then Just KR else lookup nm meta_fixed_rate meta_is_std_mce :: String -> Bool meta_is_std_mce nm = nm `elem` meta_std_mce meta_allows_i_rate :: String -> Bool meta_allows_i_rate nm = nm `elem` map m_name (filter m_i_rate meta_data)