chemart / music-ac
View on GitHubAlgorithmic chemistry for music composition — Composition without a fitness function. A molecule is a stack of lines of musical elements with a displacement, so notes, chords and harmonic functions can sit in registered columns. Recombination rules join fragments th…
How it works
Composition without a fitness function. A molecule is a stack of lines of musical elements with a displacement, so notes, chords and harmonic functions can sit in registered columns. Recombination rules join fragments that fit stylistically - a melody grows only by steps to a neighbouring note, a bar only takes a chord that contains its first note, and bars are only joined along cadence rules - and a phrase is finished when it is cut out and capped with Start and Stop, after which no rule matches it unless it still carries an avoid note. The style is in the rule set rather than in an evaluation step, so every product is well formed by construction.
- S
- objects (molecules) are stacks of lines of elements written disp#elements/ per line, the displacement counting columns relative to the first line: 0#C4D4E4/ is a melody fragment, 0#C4D4E4F4G4A4B4C5/0#TCCCCCCC/ one bar under the tonic chord C, and 0#Start...Stop/1#T.../ a finished four-bar phrase. The species id is this canonical notation; the structure is the music the object carries (notes, chords and functions) · implicit
- R
- recombination rules lhs -> rhs over patterns, where <1> matches one element, <*1> (left end of a line) and <1*> (right end) match a sequence of zero or more elements and <1..7> abbreviates <1><2>...<7>. The objects matched by the left-hand patterns are consumed and the right-hand patterns, filled with the matched elements, are produced; each wildcard occurs once on each side, so elements are conserved. The 65 rules implement the five steps of the algorithm: (1) 0#<*1>D4/ + 0#Degree/0#D4<2>/ -> 0#<*1>D4<2>/ + 0#Degree/0#D4/ grows a conjunct melody; (2) 0#E4<1..7><8><9*>/ + 0#Chord/0#TEmEmEmEmEmEmEm/ -> 0#E4<1..7>/0#TEmEmEmEmEmEmEm/ + 0#<8><9*>/ + 0#Chord/ cuts off a bar and gives it a chord containing its first note; (6) and (7) replace an avoid note via Dummy; (8) concatenates two bar sequences along a cadence; (9) cuts out a four-bar phrase that starts on a tonic bar and terminates it with Start and Stop; (10) detaches a leading non-tonic bar, which is reused. · arity 1, 2
- A
- well-stirred-multiset · none; the multiset is closed apart from the objects the rules release, and finished phrases accumulate as final products
Parameters
| name | default | meaning |
|---|---|---|
| mode enum · structural |
"homophonic" | which published system to run: homophonic is the phrase-with-chords system of [592]; the polyphonic system of [854] is not reconstructed (see decisions), so it is not offered as a choice homophonic |
| cadences enum · structural |
"published" | cadence rules of step 4: published gives the six of section 4.3 (T-D2, T-D, T-S, D-T, D2-D, D2-T), which reproduces the published total of 65 rules; with-s-t adds S-T (66 rules), which the typical cadence T-S-T and the phrase of figure 3(1) require published | with-s-t |
| avoid_notes bool · selection |
true | include the avoid-note rules of section 3.3 that replace a note dissonant with the bar's chord (8 rules plus the Dummy rule); false drops them and leaves 56 rules |
| notes_per_bar int · structural |
8 | notes in one bar; it sizes the chord line and the wildcard runs of rules (2), (8), (9) and (10) [2, 32]; published: 8 eighth notes in a bar |
| bars_per_phrase int · structural |
4 | bars cut out as one phrase by rule (9) [1, 16]; published: four-bar phrases |
| copies int · population |
1 | multiplies every count of the published initial multiset (43 kinds, 1826 objects at 1) [1, 1000] |
| steps int · population |
20000 | maximum number of collisions of the recorded run; failed draws (too few copies, or products equal to reactants) are included [0, 1e+07] |
| phrases int · population |
1 | stop once this many finished phrases are in the multiset; 0 runs the full number of steps [0, 1000]; the paper's runs collect three to five phrases in about an hour |
Algorithmic chemistry for music composition
One of the artificial chemistries of Banzhaf & Yamamoto, Artificial Chemistries (MIT Press, 2015), §16.4; first proposed by Miura & Tominaga, 2006 (homophonic); Tominaga & Setomoto, 2008 (polyphonic).
Its generator ships with the chemart library, so loading it runs no code from the hub and needs no trust_remote_code.
import chemart
net = chemart.generate_network("chemart/music-ac", seed=0) # same as "music-ac"
print(net.summary())
What to look for
- composes four-bar phrases in a defined style without any fitness function: every generated phrase has a conjunct melody, a chord per bar that contains the bar's first note, few avoid notes, a cadence-conforming chord progression and a tonic first bar (paper sections 3 and 6)
- a phrase terminated by Start and Stop is a final product: no rule matches the phrase of figure 1 any more
- jumps in an otherwise conjunct melody come from avoid notes being replaced with random notes (section 5, visible in figures 1 and 3)
- a sequence of bars that starts with a non-tonic bar is not discarded: the leading bar is detached by rule (10) and reused (figure 2, steps 10-12)
- every rule conserves elements, so the multiset's element content is invariant
- the nondeterminism of the chemistry supplies the randomness the composition needs, and several phrases grow in parallel in the same reactor
Implementation decisions
- Attribution: the v1 entry and the assignment named 'Miyamoto & Tominaga' and 'Tominaga et al.'; the book's bibliography has [592] T. Miura and K. Tominaga (GWAL-2006) and [854] K. Tominaga and M. Setomoto (EvoWorkshops 2008, LNCS 4974, pp. 463-472, doi 10.1007/978-3-540-78761-7_49). The bibliography is followed.
- The book (16.4) describes the approach only qualitatively, so everything is reconstructed from the 2006 camera-ready paper, recovered from the Wayback Machine copy of the authors' site (tomilab.net no longer resolves). The paper's own artificial chemistry is Tominaga's pattern-matching-and-recombination chemistry, catalogued separately as tominaga-stacked-strings; the music system is re-implemented here in the 2006 paper's own notation (<1>, <*1>, <1*>, <1..7>), which that module's parser does not accept because music elements contain digits (C4, D2).
- The polyphonic system of [854] is not implemented: the paper is paywalled (Springer LNCS 4974, no open version in Unpaywall, OpenAlex, CORE or the Wayback copy of the authors' site, which links only the MIDI results) and the book gives no detail. Only its existence and the survey-level description are recorded in sources; the mode parameter therefore keeps the single published choice homophonic rather than inventing a polyphonic rule set.
- The paper states '24 kinds of elements' and lists exactly 24 (8 notes, 7 chords, 4 functions, 5 control elements) but its own initial objects also use Dummy, so the implementation has 25 element kinds. The published 24 is the listed set.
- The three published totals of section 4 are reproduced exactly: 43 kinds of initial objects, 1826 objects in total (14 conjunct-motion objects at 100, 11 chord objects at 20, 1 Avoid/Dummy at 10, 8 Avoid/note at 10, 1 StartStop at 100, 8 seed notes at 2) and 65 rules (8 + 38 + 8 + 1 + 6 + 1 + 3). The 65 fixes two things the paper leaves implicit: the chord rules are one per chord object and per note of its triad with C counted as both C4 and C5 (38), and the avoid rules of G and Bm need one rule each for C4 and C5 (8), as their avoid pitch is given as 'C (where C means both C4 and C5)'.
- Cadence discrepancy, exposed as the cadences parameter. Section 3.4 lists T-S-T among the typical cadences, but its four numbered rules only add T after D or D2, and section 4.3 gives rules for T-D2, T-D, T-S, D-T, D2-D and D2-T - six rules, which is what the published total of 65 requires. Under those six, the phrase of figure 3(1) (Am, Am, C, G) is not derivable under any function assignment, because it needs S-T; figure 1 (C, G, C, G) and figures 3(2) (Em, Dm, G, Em) and 3(3) (C, Bm, Am, F) are derivable. Default published keeps the six and the rule count; with-s-t adds S-T (66 rules) and makes figure 3(1) derivable.
- Section 5 states that a phrase terminated by Start and Stop 'is no longer recombined by any rule'. That is exactly true for a phrase without avoid notes, which is the case of figure 1 (verified: no rule matches it); a phrase that still carries an avoid note is still matched by rule (6) and can be repaired. This is not treated as an erratum: section 6 only claims that a bar has 'little' dissonance, and rule (9) does not require the avoid notes to have been replaced first.
- Wildcard numbers are generated, not copied. For the default 8 notes per bar and 4 bars per phrase the generated rules (1), (2), (6), (7), (8), (9) and (10) come out character for character as printed in the paper (checked by a test); other bar sizes reuse the same scheme.
- Reactor: the paper's simulator (Cocoa/Objective-C, random collision) is not available and the authors themselves state it 'lacks sufficient theoretical foundation for simulating quantitative behaviour' and report only the products, not time series. Chemart therefore samples a rule with a weight equal to its number of ordered reactant choices, draws reactants in proportion to their copies and one match uniformly, and records the reactions that fired with their firing counts. No rates are attached anywhere, and no time series is claimed.
- Run length: the paper's runs produce three to five phrases in about an hour on a PowerPC G5 and have no terminating condition. Chemart stops after `phrases` finished phrases (default 1, reached in about 0.2 s), or after `steps` collisions; phrases=0 runs the whole budget. The published wall-clock times are not reproduced.
- Initial counts are the published ones, which the paper calls 'somewhat arbitrary', chosen so that a few phrases appear in reasonable time; copies scales them uniformly.
- v1 parameters: mode is kept with its single published choice, the callable harmony_filter becomes avoid_notes (the section 3.3 rules) together with the cadences choice (the section 3.4 filter), and the matrix seed_patterns becomes the published initial multiset with copies.
- Rules conserve elements ('conserving elements just like a chemical reaction does', section 2), so extras.conservation carries one conservation vector per element kind; the tests check m^T (P - R) = 0 for each of them.
Sources
- Banzhaf, W. & Yamamoto, L. (2015). Artificial Chemistries, section 16.4 (melodies as patterns, combination rules, random factors, chords in the patterns, stricter rules filtering out disharmonic combinations, well-stirred reactor tank) and figure 16.11 (three homophonic phrases from [592], three polyphonic phrases from [854]).
- Miura, T. & Tominaga, K. (2006). An approach to algorithmic music composition with an artificial chemistry. In Explorations in the Complexity of Possible Life (Proceedings of GWAL-7), pp. 21-30. Aka/IOS Press (book [592]). Camera-ready PDF recovered from the authors' site: https://web.archive.org/web/20061028202625id_/http://www.tomilab.net/alife/paper/MiuraMusic2CR.pdf - section 2 (notation, matching and recombination examples), section 3 (the five-step algorithm, avoid pitches, cadence rules), section 4 (elements, initial objects with counts, rules 1-10, figures 1 and 2), section 5 (simulator, results, figure 3).
- Tominaga, K. (2008). Automatic music composition by an artificial chemistry (lab page, book ref [2], http://www.tomilab.net/alife/music/): the generated samples, four-bar 8th-note phrases, and 'the following phrase is composed of two upper and lower melodies, both generated by the artificial chemistry' for the polyphonic work. Archived at https://web.archive.org/web/20090106131135id_/http://www.tomilab.net/alife/music/index.html.en
- Fernandez, J. D. & Vico, F. (2013). AI methods in algorithmic composition: a comprehensive survey. JAIR 48:513-582, p. 554 and table: the only open description of [854] found - 'Tominaga and Setomoto (2008) used this method, encoding polyphonic compositions in the strings and musical rules for counterpoint in the reaction rules of the artificial chemistry: starting from a set of simple strings, the system generated progressively more complex ones'. https://www.jair.org/index.php/jair/article/download/10845/25883
Banzhaf & Yamamoto, Artificial Chemistries (2015), §16.4
Preview at default parameters
772 species · 719 reactions · status observed · seed 1
0#G4/ + 0#Degree/0#G4F4/ -> 0#G4F4/ + 0#Degree/0#G4/ (x2) 0#C5/ + 0#Degree/0#C5B4/ -> 0#C5B4/ + 0#Degree/0#C5/ (x3) 0#B4/ + 0#Degree/0#B4C5/ -> 0#B4C5/ + 0#Degree/0#B4/ (x2) 0#C4/ + 0#Degree/0#C4D4/ -> 0#C4D4/ + 0#Degree/0#C4/ (x4) 0#E4/ + 0#Degree/0#E4D4/ -> 0#E4D4/ + 0#Degree/0#E4/ (x6) 0#F4/ + 0#Degree/0#F4E4/ -> 0#F4E4/ + 0#Degree/0#F4/ (x5) 0#D4/ + 0#Degree/0#D4E4/ -> 0#D4E4/ + 0#Degree/0#D4/ (x5) 0#F4E4/ + 0#Degree/0#E4F4/ -> 0#F4E4F4/ + 0#Degree/0#E4/ (x4) 0#B4C5/ + 0#Degree/0#C5B4/ -> 0#B4C5B4/ + 0#Degree/0#C5/ (x3) 0#E4/ + 0#Degree/0#E4F4/ -> 0#E4F4/ + 0#Degree/0#E4/ (x2) 0#F4/ + 0#Degree/0#F4G4/ -> 0#F4G4/ + 0#Degree/0#F4/ (x3) 0#C5B4/ + 0#Degree/0#B4C5/ -> 0#C5B4C5/ + 0#Degree/0#B4/ (x3) 0#C4D4/ + 0#Degree/0#D4C4/ -> 0#C4D4C4/ + 0#Degree/0#D4/ (x3) 0#C4D4C4/ + 0#Degree/0#C4D4/ -> 0#C4D4C4D4/ + 0#Degree/0#C4/ (x4) 0#G4/ + 0#Degree/0#G4A4/ -> 0#G4A4/ + 0#Degree/0#G4/ (x1) 0#F4E4F4/ + 0#Degree/0#F4G4/ -> 0#F4E4F4G4/ + 0#Degree/0#F4/ (x3) 0#C4D4C4D4/ + 0#Degree/0#D4E4/ -> 0#C4D4C4D4E4/ + 0#Degree/0#D4/ (x2) 0#A4/ + 0#Degree/0#A4B4/ -> 0#A4B4/ + 0#Degree/0#A4/ (x3) 0#D4E4/ + 0#Degree/0#E4F4/ -> 0#D4E4F4/ + 0#Degree/0#E4/ (x3) 0#A4B4/ + 0#Degree/0#B4A4/ -> 0#A4B4A4/ + 0#Degree/0#B4/ (x2) 0#G4F4/ + 0#Degree/0#F4G4/ -> 0#G4F4G4/ + 0#Degree/0#F4/ (x4) 0#A4B4A4/ + 0#Degree/0#A4G4/ -> 0#A4B4A4G4/ + 0#Degree/0#A4/ (x2) 0#C4D4C4D4E4/ + 0#Degree/0#E4F4/ -> 0#C4D4C4D4E4F4/ + 0#Degree/0#E4/ (x2) 0#B4C5B4/ + 0#Degree/0#B4C5/ -> 0#B4C5B4C5/ + 0#Degree/0#B4/ (x3) 0#C4D4C4D4E4F4/ + 0#Degree/0#F4E4/ -> 0#C4D4C4D4E4F4E4/ + 0#Degree/0#F4/ (x1) 0#F4G4/ + 0#Degree/0#G4F4/ -> 0#F4G4F4/ + 0#Degree/0#G4/ (x2) 0#E4D4/ + 0#Degree/0#D4C4/ -> 0#E4D4C4/ + 0#Degree/0#D4/ (x3) 0#G4A4/ + 0#Degree/0#A4G4/ -> 0#G4A4G4/ + 0#Degree/0#A4/ (x2) 0#C5B4C5/ + 0#Degree/0#C5B4/ -> 0#C5B4C5B4/ + 0#Degree/0#C5/ (x3) 0#D4E4F4/ + 0#Degree/0#F4E4/ -> 0#D4E4F4E4/ + 0#Degree/0#F4/ (x2) 0#F4E4F4G4/ + 0#Degree/0#G4F4/ -> 0#F4E4F4G4F4/ + 0#Degree/0#G4/ (x2) 0#F4G4F4/ + 0#Degree/0#F4E4/ -> 0#F4G4F4E4/ + 0#Degree/0#F4/ (x2) 0#G4A4G4/ + 0#Degree/0#G4A4/ -> 0#G4A4G4A4/ + 0#Degree/0#G4/ (x1) 0#C4D4C4D4E4F4E4/ + 0#Degree/0#E4D4/ -> 0#C4D4C4D4E4F4E4D4/ + 0#Degree/0#E4/ (x1) 0#C4D4C4D4/ + 0#Degree/0#D4C4/ -> 0#C4D4C4D4C4/ + 0#Degree/0#D4/ (x3) 0#B4C5B4C5/ + 0#Degree/0#C5B4/ -> 0#B4C5B4C5B4/ + 0#Degree/0#C5/ (x3) 0#G4A4G4A4/ + 0#Degree/0#A4B4/ -> 0#G4A4G4A4B4/ + 0#Degree/0#A4/ (x1) 0#A4/ + 0#Degree/0#A4G4/ -> 0#A4G4/ + 0#Degree/0#A4/ (x4) 0#G4F4G4/ + 0#Degree/0#G4F4/ -> 0#G4F4G4F4/ + 0#Degree/0#G4/ (x3) 0#G4F4G4F4/ + 0#Degree/0#F4E4/ -> 0#G4F4G4F4E4/ + 0#Degree/0#F4/ (x1) … 679 more
Generated by the uploader with chemart push; the hub never runs uploaded code.