karnatic-rhythm

Method summary
gb-plan (jathi integer) &key (beats nil) (gati 4) (extend 's) (tie-first nil) (beat-duration 1/4)
Function summary
accented-yati-phrase gati pala-lengths gap &rest args &key (type '(:srotovahayati :at-end)) &allow-other-keys
anga anga &optional (laghu-size 3) (beat 1/4)
complete-phrase-in-tala sequence &key (tala *tala*) (append-sam? nil)
gen-karnatic-cell gati jathi position &key (accented? t) (max-number nil) (min-number nil) (first-length nil) (include-length nil) (exclude-length nil) (seed nil)
gen-matras gati jathi jathi-number &key prefix suffix
make-karnatic-cycle-fn positions &key (gati-as-length t) (accented? t) (max-number nil) (min-number nil) (first-length nil) (include-length nil) (exclude-length nil) (seed nil)
preview-score-in-tala score &optional (tala *tala*) (append-sam? nil)
tala angas &optional (laghu-size 3) (beat 1/4)
tala-beat-number tala &optional (beat 1/4)
tala-plan talas &key (tala *tala*) (gati *gati*) (append-sam? nil) (accent '-) (tala-sam-accent '-) (beat-duration 1/4)
tala-time-signatures sequence &optional (tala *tala*)
*tala*    [Variable]

Globally set default tala.

*gati*    [Variable]

Current globally set gati, used by `tala-plan`.

gb-plan   (jathi integer) &key (beats nil) (gati 4) (extend 's) (tie-first nil) (beat-duration 1/4)  [Method]

Outlines (plans) the rhythmic form of a gati bhedam (gb) sequence. The result is an OMN sequence where each jathi is represented by a single note (i.e. without rhythmic phrasing).

Arguments:

  • jathi (integer): jathi of the result.

  • beats (number): duration of the result measured in beats.

  • gati (integer): gati of the result.

  • extend (s or e): if duration deviates from the duration of a full gati/jathi cycle (i.e., beats is set), whether to cut material (or add rests) at the beginning (s) or end (e).

  • tie-first (Boolean): if true, the first note of the result is tied to the second note. This is useful, e.g., if the result forms the beginning of a tala/anga and a short note (caused by cutting off notes at the beginning) should be avoided.

  • beat-duration (rational): duration of the beats used by `beats`.

Examples:

Full cycle of default gati 4, jathi 3

    (gb-plan 3) 
     => ((3/16) (3/16) (3/16) (3/16)) 

Full cycle of gati 3, jathi 5

    (gb-plan 5 :gati 3) 
     => ((5/12) (5/12) (5/12)) 

jathi 3 cut to last 2 beats.

    (gb-plan 3 :beats 2) 
     => ((1/8) (3/16) (3/16)) 

Tie first note (remainder for cut) to following note.

    (gb-plan 3 :beats 2 :tie-first T) 
     => ((1/8 tie) (3/16) (3/16)) 

If the duration is larger than *gati*, rests are inserted.

    (gb-plan 3 :beats 6) 
     => ((-3/4) (3/16) (3/16) (3/16) (3/16)) 
anga   anga &optional (laghu-size 3) (beat 1/4)  [Function]

Return an anga represented by a rhythmic value of its duration wrapped in a list.

Arguments:

  • anga (keyword): either :anudrutam, :a (1 beat), :drutam, :d (2 beats), :laghu or :l (laghu-size beats)

  • laghu-size (int): number of beats of laghu. Possible values: 3, 4, 5, 7, and 9

  • beat (ratio): length of a beat

tala   angas &optional (laghu-size 3) (beat 1/4)  [Function]

Return a tala represented by a list of angas (see function anga), i.e. a list of rhythmic values, each wrapped in a sublist.

Arguments:

  • angas (list of keyword): consisting of either :anudrutam, :a (1 beat), :drutam, :d (2 beats), :laghu or :l (laghu-size beats)

  • laghu-size (int): number of beats of laghu

  • beat (ratio): length of a beat

The seven suladi tala categories collected by Purandaradasa (each with all possible laghu sizes):

  • L D L L

  • L D L

  • D L

  • L A D

  • L D D

  • L L D D

  • L

tala-beat-number   tala &optional (beat 1/4)  [Function]

Number of beats in tala

tala-time-signatures   sequence &optional (tala *tala*)  [Function]

Return list of OMN time signatures (every anga represented as a separate bar) whose overall duration matches the length of `sequence'.

complete-phrase-in-tala   sequence &key (tala *tala*) (append-sam? nil)  [Function]

For preview within the time signature sequence corresponding to tala. Optionally, append a next tala sam. `sequence' should be a full tala or multiple talas for this to work.

Arguments:

  • sequence (OMN sequence)

  • tala (nested list of durations): a tala as returned by function tala

  • append-sam? (Boolean): whether or not to append a last beat at the very end

Note: ties in sequence are preserved, if it contains pitches (a pitch for just the first note is fine), but not for purely rhythmic sequences.

    TODO: Generalise to better work if sequence is not full tala 
preview-score-in-tala   score &optional (tala *tala*) (append-sam? nil)  [Function]

Preview score in correct time signatures for tala and with next tala same appended.

Arguments:

  • score (preview-score format score)

  • tala (nested list of durations): a tala as returned by function tala

  • append-sam? (Boolean): whether or not to append a last beat at the very end

gen-karnatic-cell   gati jathi position &key (accented? t) (max-number nil) (min-number nil) (first-length nil) (include-length nil) (exclude-length nil) (seed nil)  [Function]

Returns a Karnatic rhythmic cell (list of rhythmic values) or a list of such cells (if `position' is a list). The shape of the resulting cell(s) can be controlled in many ways, allowing to generate, e.g., rhythms that are similar even if they are in different gatis or jathis.

See Reina (2016) for details on terms like gati, jathi and matra.

Arguments:

  • gati (integer -- commonly in {3, 4, 5, 7}-- or list of them): gati for the cell(s) to generate.

  • jathi (integer in range 1-7, or list of them): jathi for the cell(s) to generate. 1 and 2 no standard Karnatic jathi, but added for more flexibility preserving consistency. BUG: 7 not yet defined/supported

  • position (integer, '?, or list of either): specifies which cell of the available options to generate. If no filtering is enabled (see further arguments below) then the list of available options are all the possible standard subdivisions of a 'beat' depending on the current jathi as listed by (Reina, 2016, p. 23f). These options are sorted by the number of notes in rhythmic cells (fewest first), and in case of equal note numbers the length of notes starting with the first note (longer first note first). So, the position 0 is always a single note per beat/cell (length depends on gati and jathi) and so on. If `position' exceeds the number of available options, the last option is return, which is always an even subdivision of the cell in jathi matras. If `position' is '? then the position is randomised.

  • accented? (Boolean, or binary integer, i.e. 0 or 1): whether the returned cells potentially carry durational accents on the start of the cells (or on an immediately following longer note). If accented? is nil (or 0) then the cell(s) carry a durational accent that is not on the start of the cell. Binary integers are supported so that values for this argument can be generated with Opusmodus' binary number generators.

  • max-number/min-number (integer or list of them): max/min number of notes in the cell(s).

  • first-length (ratio or OMN length, or list of either): length of the first note in cell(s).

  • include-length/exclude-length (ratio or OMN length, or list of either): length values that must be included in or excluded from the cell(s).

  • seed (integer): the seed to use for the randomised position, is position is '?.

NOTE: For resulting in a full number of beats, the number of elements in position should be a multiple of gati. Remember that (with constant gati and jathi for one period), gati = number of accents and yati = number of beats.

Examples:

The first position is always a single note per cell (if no other filtering is selected)

    (gen-karnatic-cell 4 4 0) 

Generating multiple cells, and showing the order of cells in this gati and jathi without filtering (only cells carrying potentially a durational accent on the first note of the cell).

    (gen-karnatic-cell 4 4 '(0 1 2 3 4)) 

Setting a different jathi.

    (gen-karnatic-cell 4 5 '(0 1 2 3 4)) 

If position exceeds the range of possible cell, the last cell is chosen (which is always an even subdivision of the full cell length into `yati' matras.

    (gen-karnatic-cell 4 4 100) 

If position receives a list, also all other arguments can be lists (of the same length), e.g., different jathis. Note that equal positions in different jathis tend to result in similar cells.

    (gen-karnatic-cell 4 '(3 4 5) '(1 1 1)) 

Filtering arguments can further shape the result. The meaning of the position argument changes accordingly, always depending on the remaining number of rhythmic options for cells. E.g., the minimum number of notes per cell can be set...

    (gen-karnatic-cell 4 4 0 :min-number 2) 

... or the maximum number of notes. Note that the position is randomised here.

    (gen-karnatic-cell 4 4 '? :max-number 3) 

... or the first note value in the cell can be set.

    (gen-karnatic-cell 4 4 '(1 1 1) :first-length 1/8) 

All these filter arguments also support lists for setting different values for each sublist.

    (gen-karnatic-cell 4 4 '(0 0) :exclude-length '(e q)) 

Again, an example with randomised positions, but here the seed is fixed.

    (gen-karnatic-cell 4 4 '(? ?) :min-number 2 :seed 1) 

Filtering can remove all options for cells, in which case nil returned.

    (gen-karnatic-cell 4 4 0 :min-number 5) 

You can of course overwrite the resulting time signature with `omn-to-time-signature'. If you want to keep track of where the accents are located, you could mark them before this transformation. You could then manually later revise the notation to instead you the beam-breaking that Reina recommends.

    (omn-to-time-signature  
      (articulate-bars (gen-karnatic-cell 4 5 '(0 6 3 2 1 0)) 
                        :accent 'marc) 
     '(4 4)) 

For more examples see also https://opusmodus.com/forums/topic/1097-updated-library-of-many-custom-opusmodus-functions/?tab=comments#comment-3497

You may want to consider further transforming results with rhythm transformations functions like, e.g., `tie-whole-notes'.

BUGS:

The argument min-number is seemingly not fully working yet:

    (gen-karnatic-cell 4 5 '(? ? ? ?) :min-number '(3 3 3 3) :seed 1) 
     => ((1/8 1/8 1/16) (3/16 1/16 1/16) (1/16 1/16 1/16 1/16 1/16) (1/8 1/8 1/16))  

Notes:

  • Reina, R. (2016) Applying Karnatic Rhythmical Techniques to Western Music. Routledge.

make-karnatic-cycle-fn   positions &key (gati-as-length t) (accented? t) (max-number nil) (min-number nil) (first-length nil) (include-length nil) (exclude-length nil) (seed nil)  [Function]

Return function similar to gen-karnatic-cell, but with a predefined list of positions.

Arguments:

  • gati-as-length (Boolean): if true, uses gati number elements of the positions (results in a full number of beats). gati then must be an integer. Otherwise use the full positions always. Other arguments inherited from gen-karnatic-cell.

tala-plan   talas &key (tala *tala*) (gati *gati*) (append-sam? nil) (accent '-) (tala-sam-accent '-) (beat-duration 1/4)  [Function]

Some mini language for outlining the rhythmic form of a tala sequence, in particular gati bhedam sequences. The result is a rhythmic OMN sequence (expressed in the time signature corresponding to `tala`), where each jathi is represented by a single note (i.e. without rhythmic phrasing).

Arguments:

  • talas (nested list): a sequence of talas (or tala groups) expressed in a mini language described below.

  • tala (nested list of durations): a tala as returned by function `tala`.

  • gati (integer): the default gati of the result.

  • append-sam? (Boolean): whether or not to append a last beat at the very end.

  • accent (symbol): articulation to use on every first note of a jathis.

  • tala-sam-accent (symbol): articulation to use on every first note of a tala (group). Intended for debugging/proofreading results.

  • beat-duration (rational): duration of a beat (for the symbol `beat`).

Each element of `talas` is a sublist in the following format. Within such sublist, an integer represents a full jathi cycle (i.e. a gati bhedam sequence with constant jathi starting and ending on a beat). The integer specifies the jathi and also the duration of that cycle measured in beats. The symbol `beat` represents a full beat in the result, while the symbol tied-beat is a beat tied to whatever follows. Additionally, any other rhythmic OMN sequence can occur within a tala specification (inserted into the tala time signatures in the result). For example, a partial jathi cycle can be expressed with the function `gb-plan` as demonstrated in an example below.

IMPORTANT: It is the responsibility of the user to ensure that the elements within a tala spec actually 'fit' into the given tala. This freedom allows to compose gati bhedam sequences that last multiple talas. However, with the argument `tala-sam-accent` it is easy to ensure that the beginnings of all tala (groups) fall on the intended metric position.

Examples:

A specification of two L D5 talas in gati 5. The first tala is rather simple and accents tala an anga sam. The second tala is a gati bhedam sequence of two full cycles that nevertheless ends on tala sam again.

    (setf *tala* (tala '(:d :l) 5)) 

    (tala-plan '(;; beat expands to '((1/4)) 
     	        (beat beat 5) 
     	        ;; gati bhedam 
     	        (3 4)) 
     	       ;; global gati of the result 
     	       :gati 5) 

An example demonstrating further tala plan features.

    (tala-plan `((beat beat 5) 
     	         ;; partial gati bhedam cycle 
     	         ;; NOTE: the global gati is not inherited by independent  
                  ;; functions like gb-plan and therefore set again  
     	         (beat beat beat beat ,(gb-plan 4 :beats 3 :gati 5)) 
     	         ;; tala group lasting over two talas with a change of gati 
     	         (4 4 6 :gati 3) 
     	         ;; simple reprise 
     	         (beat beat 5)) 
     	       :gati 5 
     	       ;; Append a tala sam at the end 
     	       :append-sam? T) 

Polyphonic example: monophonic results of tala-plan combined in polyphonic score To have multiple voices with longer tala sequences more easily synchornised, consider somehow splitting the tala sequences into multiple calls of `tala-plan` per part.

    `(:treble ,(tala-plan '((beat beat 5))) 
       :bass ,(tala-plan '((3 4)))) 

gen-matras   gati jathi jathi-number &key prefix suffix  [Function]

Generates a sequence of matras (equal note durations) where `gati' defines the beat subdivision, `jathi' the number of matras per 'bar' (sublist) and `jathi-number' the resulting number of sublists.

Arguments:

  • gati (int)

  • jathi (int)

  • jathi-number (int)

  • prefix (length value or length sequence, possibly nested): preceeding phrase

  • suffix (length value or length sequence, possibly nested): succeeding phrase

Examples:

gati 5 (quintuplets), jathi 4

    (gen-matras 5 4 3) 

gati 5 (quintuplets), jathi 4, but preceeded by a quarter note rest.

    (gen-matras 5 4 3 :prefix '-q) 

Notes:

See Reina (2016) for details on the terms matras, gati and jathi.

  • Reina, R. (2016) Applying Karnatic Rhythmical Techniques to Western Music. Routledge.

accented-yati-phrase   gati pala-lengths gap &rest args &key (type '(:srotovahayati :at-end)) &allow-other-keys  [Function]

Generates the matras sequence for a yati phrase, see Reina (2016, p. 205ff) for details. Resulting sublists are jathis for potential post-processing (e.g., adding an accent on their first notes) before redefining the metric structure (usually to follow the tala, e.g., with `omn-to-time-signature').

NOTE: In contrast to Karnatic music, resulting accents are expressed by durational accents by this function. Hence the word `accented' in the function name.

Arguments:

  • gati (OMN length): beat subdivision

  • pala-lengths (list of ints): number of matras per pala

  • gap (OMN length, typically a rest): length of gaps between palas (always constant). For mridangamyati phrases, when you need different gap lengths, simply append two calls to the present function.

  • type (list of two keywords): specifies first the type of the yati phrase (:srotovahayati, where matras are added or :gopuchayati, where matras are removed over time). Secondly, it sets at which side the pala matras are added or removed (:at-end :at-front). There are four combinations in total. You can compose mridangamyati and damaruyati yati phrases by combining the results of two calls of this function. Note that inserting matras in the middle is currently not supported.

Additionally, all `durational-accent' key args are supported.

Examples:

    (accented-yati-phrase 's '(4 7 10 13) '-e :type '(:srotovahayati :at-end) :divide-prob 0.3 :merge-prob 0.7 :seed 1) 

    (accented-yati-phrase '3q '(4 7 10 13) '-3e :type '(:gopuchayati :at-front) :divide-prob 0.7 :merge-prob 0.5 :seed 3) 

Notes:

  • Reina, R. (2016) Applying Karnatic Rhythmical Techniques to Western Music. Routledge.