Karya, built on 2023-08-29T07:47:28 (patch 7a412d5d6ba4968ca4155ef276a062ccdeb9109a)
Safe HaskellSafe-Inferred

Derive.C.Bali.Gangsa

Description

Calls for gangsa techniques. Gangsa come in polos and sangsih pairs, and play either kotekan patterns or play unison or parallel parts.

Kotekan patterns have a number of features in common. They are all transpositions from a base pitch. Rhythmically, they consist of notes with a constant duration, that line up at the end of an event's range, and the last duration is negative (i.e. implicit, depending on the next note). They use polos and sangsih and may switch patterns when the a kotekan speed threshold is passed. Notes are also possibly muted.

There are a number of ways this can be extended:

  • Use any attribute instead of just mute.
  • More instruments than just polos and sangsih.
  • Multiple kotekan thresholds.

The first two are supported at the KotekanNote level of abstraction. For the others, I have to either directly use Notes or create a new abstraction:

  • Variable durations.
Synopsis

Documentation

instrument postproc

mute_postproc :: Attrs.Attributes -> Score.Event -> (Score.Event, [Log.Msg]) Source #

Variable mute for gangsa. Intended for the inst_postproc field. This interprets Controls.mute and turns it into either a %mod control or mute_attr.

ngoret

patterns

data KotekanPattern Source #

There are 4 ways to realize a kotekan:

  1. Undivided. Since it's undivided it could be unison or kempyung.
  2. Slow but divided. Play all the notes, but sangsih and polos are kempyung on the outer notes. 3, 4. Ngotek, in telu and pat versions.

data Pasang a Source #

Constructors

Pasang 

Fields

Instances

Instances details
Show a => Show (Pasang a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

showsPrec :: Int -> Pasang a -> ShowS #

show :: Pasang a -> String #

showList :: [Pasang a] -> ShowS #

Eq a => Eq (Pasang a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

(==) :: Pasang a -> Pasang a -> Bool #

(/=) :: Pasang a -> Pasang a -> Bool #

Pretty.Pretty a => Pretty.Pretty (Pasang a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

data Realization a Source #

Constructors

Realization 

Fields

Instances

Instances details
Show a => Show (Realization a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Eq a => Eq (Realization a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Pretty.Pretty a => Pretty.Pretty (Realization a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

norot

c_norot :: Bool -> Maybe.Maybe Bool -> Generator Note Source #

Initially I implemented this as a postproc, but it now seems to me that it would be more convenient as a generator. In any case, as a postproc it gets really complicated.

norot_sequence :: Bool -> (DeriveT.Transposed -> Cycle) -> (DeriveT.Transposed -> Cycle) -> Maybe.Maybe DeriveT.Pitch -> Maybe.Maybe DeriveT.Pitch -> RealTime.RealTime -> Deriver (Maybe.Maybe PitchedCycle, Maybe.Maybe PitchedCycle, Maybe.Maybe PitchedCycle) Source #

Figure out the appropriate cycles for each norot phase. There are 3 phases: an optional preparation for the current pitch, a variable length sustain, and an optional preparation for the next pitch.

prepare_sustain :: Bool -> ScoreTime -> (Maybe.Maybe Bool, Bool) -> Types.Orientation -> (ScoreTime, ScoreTime) -> (Maybe.Maybe ((Bool, Bool), (ScoreTime, ScoreTime)), Maybe.Maybe ((Bool, Bool), (ScoreTime, ScoreTime))) Source #

Figure out parameters for the sustain and prepare phases. Why is this SO COMPLICATED.

TODO this is still used by Reyong. If I can simplify reyong norot too then I can get rid of it.

infer_prepare Source #

Arguments

:: PassedArgs a 
-> Maybe.Maybe Bool

True to prepare, False to not, Nothing to prepare if this note touches the next one.

-> Deriver (Maybe.Maybe DeriveT.Pitch) 

norot_steps Source #

Arguments

:: Scale 
-> Maybe.Maybe Pitch.Pitch 
-> NorotStyle 
-> DeriveT.Transposed

this is to figure out if the sangsih part will be in range

-> Pasang (Pitch.Step, Pitch.Step) 

kotekan

regular

c_kotekan_regular :: Bool -> Maybe.Maybe Text -> KotekanStyle -> Generator Note Source #

For regular kotekan, the sangsih can be automatically derived from the polos.

implementation

realize_kotekan_pattern Source #

Arguments

:: (Bool, Bool)

include (initial, final)

-> (ScoreTime, ScoreTime) 
-> Types.Orientation 
-> ScoreTime 
-> DeriveT.Pitch 
-> (ScoreTime -> Bool) 
-> Repeat 
-> Cycle 
-> NoteDeriver 

Take a Cycle, which is an abstract description of a pattern via KotekanNotes, to real notes in a NoteDeriver.

type Kernel = [Atom] Source #

data Atom Source #

Constructors

Gap

a gap in the kotekan pattern

Rest

a rest will be filled in by the other part

Low 
High 

Instances

Instances details
Show Atom Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

showsPrec :: Int -> Atom -> ShowS #

show :: Atom -> String #

showList :: [Atom] -> ShowS #

Eq Atom Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

(==) :: Atom -> Atom -> Bool #

(/=) :: Atom -> Atom -> Bool #

Ord Atom Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

compare :: Atom -> Atom -> Ordering #

(<) :: Atom -> Atom -> Bool #

(<=) :: Atom -> Atom -> Bool #

(>) :: Atom -> Atom -> Bool #

(>=) :: Atom -> Atom -> Bool #

max :: Atom -> Atom -> Atom #

min :: Atom -> Atom -> Atom #

Pretty.Pretty Atom Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

end_on_zero :: Cycle -> Cycle Source #

Make both parts end on zero by subtracting the pitch of the final non-interlocking note.

rotate :: Int -> [a] -> [a] Source #

rotations :: [a] -> [[a]] Source #

all kernels

find_kernel :: Kernel -> Maybe.Maybe (Kernel, Bool, Int) Source #

Find a kernel as a rotation or inversion of one of the standard ones.

implementation

data Repeat Source #

Constructors

Repeat 
Once 

Instances

Instances details
Show Repeat Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Pretty.Pretty Repeat Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

type Cycle = Realization [[KotekanNote]] Source #

(interlocking pattern, non-interlocking pattern)

Each list represents coincident notes. [] is a rest.

data Note a Source #

Constructors

Note 

Instances

Instances details
Functor Note Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

fmap :: (a -> b) -> Note a -> Note b #

(<$) :: a -> Note b -> Note a #

Show a => Show (Note a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

showsPrec :: Int -> Note a -> ShowS #

show :: Note a -> String #

showList :: [Note a] -> ShowS #

Pretty.Pretty a => Pretty.Pretty (Note a) Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Methods

pretty :: Note a -> Text Source #

format :: Note a -> Doc Source #

formatList :: [Note a] -> Doc Source #

data KotekanNote Source #

High level description of a note. This goes into Note before it becomes a Derive.NoteDeriver.

Constructors

KotekanNote 

Fields

Instances

Instances details
Show KotekanNote Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Pretty.Pretty KotekanNote Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

under_threshold_function Source #

Arguments

:: (RealTime.RealTime -> RealTime.RealTime) 
-> ScoreTime 
-> Deriver (ScoreTime -> Bool)

say if a note at this time with the given duration would be under the kotekan threshold

realize_pattern Source #

Arguments

:: Repeat

Once will just call get_cycle at the start time. Repeat will start the cycle at t+1 because t is the initial, so it's the end of the cycle.

-> Types.Orientation

align to start or end

-> (Bool, Bool) 
-> ScoreTime 
-> ScoreTime 
-> ScoreTime 
-> (ScoreTime -> [[a]])

Get one cycle of notes, starting at the time.

-> [Note a] 

Repeatedly call a cycle generating function to create notes. The result will presumably be passed to realize_notes to convert the notes into NoteDerivers.

cycles :: (t -> [a]) -> [t] -> [(t, a)] Source #

Pair each t with an a, asking the function for more as as needed.

cycles_end :: (t -> [a]) -> [t] -> [(t, a)] Source #

This is like cycles, but the last cycle is aligned to the end of the ts, chopping off the front of the cycle if necessary.

zip_end :: [a] -> [b] -> [(a, b)] Source #

Like zip, but two sequences are aligned at at their ends, instead of their starts.

realize_notes :: (a -> NoteDeriver) -> [Note a] -> NoteDeriver Source #

Turn Notes into a NoteDeriver.

data NorotStyle Source #

Style for non-interlocking norot. Interlocking norot is always the upper neighbor (or lower on the top key).

Constructors

Default

Norot is emitted as the current instrument, which should be converted into kempyung or unison by a postproc.

Diamond

Norot in the diamond pattern, where sangsih goes down.

data KotekanStyle Source #

Constructors

Telu 
Pat 

Instances

Instances details
Bounded KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Enum KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Show KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Eq KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

ShowVal.ShowVal KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Typecheck.ToVal KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

Typecheck.Typecheck KotekanStyle Source # 
Instance details

Defined in Derive.C.Bali.Gangsa

postproc

c_kempyung :: Library.Calls Note Source #

I could do this in two different ways: Eval normally, then eval with +kempyung, and make instrument note call understand it. Or, postproc, transpose, and check if the nn is above a limit. The first one would let the instrument choose how it wants to interpret +kempyung while letting this call remain generic, but let's face it, it only really means one thing. The second seems a little simpler since it doesn't need a cooperating note call.

So postproc it is.

realize calls

type NoltolArg = (RealTime.RealTime, RealTime.RealTime, Signal.Y) Source #

(noltol-time, kotekan-dur, damp-dyn)

realize_noltol :: NoltolArg -> Score.Event -> Maybe.Maybe Score.Event -> NoteDeriver Source #

If the next note of the same instrument is below a threshold, the note's off time is replaced with a +mute.

cancel-pasang

cancel_strong_final :: [Score.Event] -> Either Text [Score.Event] Source #

Kotekan ends with a final, which cancels normal, but loses to strong. This is like Postproc.cancel_strong_weak, except it adds final_flag, so I can have the end of a kotekan override, but still be overidden with an explicit strong note.

pasang_key :: Postproc.Key (Either ScoreT.Instrument (ScoreT.Instrument, ScoreT.Instrument), Maybe.Maybe Text) Source #

Match any of polos, sangsih, and pasang to each other. Since polos and sangsih together are considered one voice, a sangsih start is note end for a polos note.

implementation

get_pitch :: PassedArgs a -> Deriver DeriveT.Pitch Source #

Get pitch for a kotekan call.