Karya, built on Mon Jul 24 11:39:07 PDT 2017 (patch 33511aca01257b76b88de7c7a2763b7a965c084e)

Derive.Call.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 PatternNote level of abstraction. For the others, I have to either directly use Notes or create a new abstraction:

• Variable durations.

Synopsis

# instrument postproc

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.

# patterns

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.

Constructors

 KotekanPattern Fields

Instances

 # Methods # MethodsshowList :: [KotekanPattern] -> ShowS # # Methods

data Pasang a Source #

Constructors

 Pasang Fieldspolos :: a sangsih :: a

Instances

 Eq a => Eq (Pasang a) # Methods(==) :: Pasang a -> Pasang a -> Bool #(/=) :: Pasang a -> Pasang a -> Bool # Show a => Show (Pasang a) # MethodsshowsPrec :: Int -> Pasang a -> ShowS #show :: Pasang a -> String #showList :: [Pasang a] -> ShowS # # Methodspretty :: Pasang a -> Text Source #format :: Pasang a -> Doc Source #formatList :: [Pasang a] -> Doc Source #

data Realization a Source #

Constructors

 Realization Fieldsinterlocking :: a non_interlocking :: a

Instances

 Eq a => Eq (Realization a) # Methods(==) :: Realization a -> Realization a -> Bool #(/=) :: Realization a -> Realization a -> Bool # Show a => Show (Realization a) # MethodsshowsPrec :: Int -> Realization a -> ShowS #show :: Realization a -> String #showList :: [Realization a] -> ShowS #

Constructors

 IrregularPattern Fieldsir_polos :: [Char] ir_sangsih4 :: [Char] ir_polos_ngotek :: [Char] ir_sangsih_ngotek3 :: [Char] ir_sangsih_ngotek4 :: [Char]

Instances

 # MethodsshowList :: [IrregularPattern] -> ShowS #

## norot

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.

Realize the output of norot_sequence.

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.

Constructors

 PitchedCycle !BaseTypes.Pitch !Cycle

prepare_sustain :: Bool -> ScoreTime -> (Maybe.Maybe Bool, Bool) -> Event.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.

Prepare for the next pitch if this note touches the next one.

Arguments

 :: Scale -> Maybe.Maybe Pitch.Pitch -> NorotStyle -> BaseTypes.Transposed this is to figure out if the sangsih part will be in range -> Pasang (Pitch.Step, Pitch.Step)

# kotekan

## regular

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

### implementation

Arguments

 :: (Bool, Bool) include (initial, final) -> (ScoreTime, ScoreTime) -> Event.Orientation -> ScoreTime -> BaseTypes.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

 # Methods(==) :: Atom -> Atom -> Bool #(/=) :: Atom -> Atom -> Bool # # Methodscompare :: Atom -> Atom -> Ordering #(<) :: Atom -> Atom -> Bool #(<=) :: Atom -> Atom -> Bool #(>) :: Atom -> Atom -> Bool #(>=) :: Atom -> Atom -> Bool #max :: Atom -> Atom -> Atom #min :: Atom -> Atom -> Atom # # MethodsshowsPrec :: Int -> Atom -> ShowS #show :: Atom -> String #showList :: [Atom] -> ShowS # # MethodsformatList :: [Atom] -> Doc 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 a kernel as a rotation or inversion of one of the standard ones.

## implementation

data Repeat Source #

Constructors

 Repeat Once

Instances

 # MethodsshowsPrec :: Int -> Repeat -> ShowS #showList :: [Repeat] -> ShowS # # MethodsformatList :: [Repeat] -> Doc Source #

type Cycle = Realization [[KotekanNote]] Source #

(interlocking pattern, non-interlocking pattern)

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

data Note a Source #

Constructors

 Note Fieldsnote_start :: !ScoreTime note_duration :: !ScoreTime note_flags :: !Flags.FlagsUsed for final_flag.note_data :: !a

Instances

 # Methodsfmap :: (a -> b) -> Note a -> Note b #(<\$) :: a -> Note b -> Note a # Show a => Show (Note a) # MethodsshowsPrec :: Int -> Note a -> ShowS #show :: Note a -> String #showList :: [Note a] -> ShowS # # Methodspretty :: Note a -> Text Source #format :: Note a -> Doc Source #formatList :: [Note a] -> Doc Source #

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

Constructors

 KotekanNote Fieldsnote_instrument :: !(Maybe.Maybe Instrument)If Nothing, retain the instrument in scope. Presumably it will be later split into polos and sangsih by a unison or kempyung call.note_steps :: !Pitch.Step note_muted :: !Bool

Instances

 # MethodsshowList :: [KotekanNote] -> ShowS # # MethodsformatList :: [KotekanNote] -> Doc Source #

Arguments

 :: BaseTypes.ControlRef -> ScoreTime -> Deriver (ScoreTime -> Bool) say if a note at this time with the given duration would be under the kotekan threshold

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. -> Event.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.

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.

Instances

 # Methods # Methods # Methods # MethodsshowList :: [NorotStyle] -> ShowS # # Methods # Methods # Methods

Constructors

 Telu Pat

Instances

 # Methods # Methods # Methods # MethodsshowList :: [KotekanStyle] -> ShowS # # Methods # Methods # Methods

# postproc

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

(noltol-time, kotekan-dur)

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

## cancel-pasang

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.

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 for a kotekan call.