haskore-0.0.5: src/Haskore/Interface/CSound/SoundMap.hs
-- cf. SuperCollider.SoundMap
-- this module shall replace InstrumentMap in the long term
module Haskore.Interface.CSound.SoundMap where
import qualified Haskore.Interface.CSound.Orchestra as Orchestra
import Haskore.Interface.CSound.Orchestra
(SigExp, noteDur, noteVel, notePit, pField)
import Haskore.Interface.CSound (PField, Instrument)
import Haskore.General.Utility (toMaybe)
import Data.Maybe (mapMaybe)
type SoundId = Instrument
type InstrumentId = SoundId
type DrumId = SoundId
type Attribute = PField
type AttributeList = [Attribute]
type ToSound instr = instr -> (AttributeList, SoundId)
attributeControl :: Int -> SigExp
attributeControl n = pField (6+n)
type InstrumentTable out instr = [(instr, InstrumentSigExp out)]
type InstrumentTableWithAttributes out instr = [InstrumentAssociation out instr]
type InstrumentSigExp out = SigExp -> SigExp -> SigExp -> out
data InstrumentAssociation out instr =
InstrumentAssociation InstrumentId (instr -> Maybe AttributeList) out
lookupInstrument :: InstrumentTableWithAttributes out instr -> ToSound instr
lookupInstrument table instr =
case mapMaybe (\(InstrumentAssociation name toAttributes _) ->
fmap (\ps -> (ps,name)) (toAttributes instr)) table of
[] -> error "SuperCollider.InstrumentMap.lookup: instrument not found"
[x] -> x
_ -> error "SuperCollider.InstrumentMap.lookup: multiple instruments found"
instrumentTableToInstrBlocks ::
InstrumentTableWithAttributes out instr -> [Orchestra.InstrBlock out]
instrumentTableToInstrBlocks =
map (\(InstrumentAssociation i _ out) -> Orchestra.InstrBlock i 0 out [])
addInstrumentControls :: InstrumentSigExp out -> out
addInstrumentControls graph = graph noteDur noteVel notePit
instrumentAssociation ::
(parameterTuple -> AttributeList) ->
(graph -> InstrumentSigExp out) ->
InstrumentId -> (instr -> Maybe parameterTuple) ->
graph ->
InstrumentAssociation out instr
instrumentAssociation makeAttributeList makeInstrumentSigExp name select graph =
InstrumentAssociation
name
(fmap makeAttributeList . select)
(addInstrumentControls $ makeInstrumentSigExp graph)
instrument ::
InstrumentId -> (instr -> Maybe ()) -> (InstrumentSigExp out) ->
InstrumentAssociation out instr
instrument = instrumentAssociation (\() -> []) id
-- simplified variant of 'instrument' for comparable @instrument@ types
instrumentEq :: Eq instrument =>
InstrumentId -> instrument -> (InstrumentSigExp out) ->
InstrumentAssociation out instrument
instrumentEq name instrumentId =
instrument name (\x -> toMaybe (instrumentId==x) ())
instrument1 ::
InstrumentId -> (instr -> Maybe Attribute) ->
(SigExp -> InstrumentSigExp out) ->
InstrumentAssociation out instr
instrument1 =
instrumentAssociation
(\p0 -> [p0])
(\graph -> graph (attributeControl 0))
instrument2 ::
InstrumentId -> (instr -> Maybe (Attribute, Attribute)) ->
(SigExp -> SigExp -> InstrumentSigExp out) ->
InstrumentAssociation out instr
instrument2 =
instrumentAssociation
(\(p0,p1) -> [p0,p1])
(\graph -> graph
(attributeControl 0)
(attributeControl 1))
instrument3 ::
InstrumentId -> (instr -> Maybe (Attribute, Attribute, Attribute)) ->
(SigExp -> SigExp -> SigExp -> InstrumentSigExp out) ->
InstrumentAssociation out instr
instrument3 =
instrumentAssociation
(\(p0,p1,p2) -> [p0,p1,p2])
(\graph -> graph
(attributeControl 0)
(attributeControl 1)
(attributeControl 2))
instrument4 ::
InstrumentId -> (instr -> Maybe (Attribute, Attribute, Attribute, Attribute)) ->
(SigExp -> SigExp -> SigExp -> SigExp -> InstrumentSigExp out) ->
InstrumentAssociation out instr
instrument4 =
instrumentAssociation
(\(p0,p1,p2,p3) -> [p0,p1,p2,p3])
(\graph -> graph
(attributeControl 0)
(attributeControl 1)
(attributeControl 2)
(attributeControl 3))
type DrumTable out drum = [(drum, DrumSigExp out)]
type DrumTableWithAttributes out drum = [DrumAssociation out drum]
type DrumSigExp out = SigExp -> SigExp -> out
data DrumAssociation out drum =
DrumAssociation DrumId (drum -> Maybe AttributeList) out
lookupDrum :: DrumTableWithAttributes out drum -> ToSound drum
lookupDrum table drumId =
case mapMaybe (\(DrumAssociation name toAttributes _) ->
fmap (\ps -> (ps,name)) (toAttributes drumId)) table of
[] -> error "SuperCollider.InstrumentMap.lookup: drum not found"
[x] -> x
_ -> error "SuperCollider.InstrumentMap.lookup: multiple drums found"
drumTableToInstrBlocks :: DrumTableWithAttributes out instr -> [Orchestra.InstrBlock out]
drumTableToInstrBlocks =
map (\(DrumAssociation i _ out) -> Orchestra.InstrBlock i 0 out [])
addDrumControls :: DrumSigExp out -> out
addDrumControls graph = graph noteDur noteVel
drumAssociation ::
(parameterTuple -> AttributeList) ->
(graph -> DrumSigExp out) ->
DrumId -> (drum -> Maybe parameterTuple) ->
graph ->
DrumAssociation out drum
drumAssociation makeAttributeList makeDrumSigExp name select graph =
DrumAssociation
name
(fmap makeAttributeList . select)
(addDrumControls $ makeDrumSigExp graph)
drum ::
DrumId -> (drum -> Maybe ()) -> (DrumSigExp out) ->
DrumAssociation out drum
drum = drumAssociation (\() -> []) id
-- simplified variant of 'drum' for comparable @drum@ types
drumEq :: Eq drum =>
DrumId -> drum -> (DrumSigExp out) ->
DrumAssociation out drum
drumEq name drumId =
drum name (\x -> toMaybe (drumId==x) ())
drum1 ::
DrumId -> (drum -> Maybe Attribute) ->
(SigExp -> DrumSigExp out) ->
DrumAssociation out drum
drum1 =
drumAssociation
(\p0 -> [p0])
(\graph -> graph (attributeControl 0))
drum2 ::
DrumId -> (drum -> Maybe (Attribute, Attribute)) ->
(SigExp -> SigExp -> DrumSigExp out) ->
DrumAssociation out drum
drum2 =
drumAssociation
(\(p0,p1) -> [p0,p1])
(\graph -> graph
(attributeControl 0)
(attributeControl 1))
drum3 ::
DrumId -> (drum -> Maybe (Attribute, Attribute, Attribute)) ->
(SigExp -> SigExp -> SigExp -> DrumSigExp out) ->
DrumAssociation out drum
drum3 =
drumAssociation
(\(p0,p1,p2) -> [p0,p1,p2])
(\graph -> graph
(attributeControl 0)
(attributeControl 1)
(attributeControl 2))
drum4 ::
DrumId -> (drum -> Maybe (Attribute, Attribute, Attribute, Attribute)) ->
(SigExp -> SigExp -> SigExp -> SigExp -> DrumSigExp out) ->
DrumAssociation out drum
drum4 =
drumAssociation
(\(p0,p1,p2,p3) -> [p0,p1,p2,p3])
(\graph -> graph
(attributeControl 0)
(attributeControl 1)
(attributeControl 2)
(attributeControl 3))