bitcomposer 2.0.0rc2__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/PKG-INFO +210 -152
  2. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/README.md +209 -151
  3. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/__init__.py +1 -1
  4. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/cli.py +21 -7
  5. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/composer.py +2 -2
  6. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/instruments.py +4 -1
  7. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/__init__.py +4 -3
  8. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/bit.py +32 -9
  9. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/library.py +18 -9
  10. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/megamanx.py +1 -1
  11. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/packfile.py +51 -5
  12. bitcomposer-2.1.0/bitcomposer/performance.py +213 -0
  13. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/backend.py +50 -8
  14. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/engine.py +259 -11
  15. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/icons/bitcomposer.svg +9 -5
  16. bitcomposer-2.1.0/bitcomposer/player/level.py +159 -0
  17. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/openmpt.py +47 -1
  18. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/qml/Main.qml +303 -116
  19. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/update.py +3 -3
  20. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/window.py +1 -1
  21. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/samples/__init__.py +26 -3
  22. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/score.py +25 -5
  23. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/__main__.py +3 -2
  24. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/brr.py +4 -4
  25. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/convert.py +10 -1
  26. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/tuning.py +23 -0
  27. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/beat.py +86 -0
  28. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/drums.py +22 -2
  29. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/events.py +19 -1
  30. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/harmony.py +1 -1
  31. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/lead.py +104 -34
  32. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/pack.py +65 -9
  33. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/packtables.py +66 -12
  34. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/phrases.py +2 -2
  35. bitcomposer-2.1.0/bitcomposer/translate/reading.py +245 -0
  36. bitcomposer-2.1.0/bitcomposer/translate/rhythm/__init__.py +9 -0
  37. bitcomposer-2.1.0/bitcomposer/translate/rhythm/arrangement.py +4126 -0
  38. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/rhythm/cells.py +137 -19
  39. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/rhythm/chords.py +18 -0
  40. bitcomposer-2.1.0/bitcomposer/translate/rhythm/own.py +73 -0
  41. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/rhythm/readings.py +410 -18
  42. bitcomposer-2.1.0/bitcomposer/translate/roles.py +599 -0
  43. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/store.py +34 -3
  44. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/tables.py +17 -7
  45. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/vocab.py +1 -1
  46. bitcomposer-2.1.0/bitcomposer/translate/whole/__init__.py +8 -0
  47. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/whole/measures.py +12 -4
  48. bitcomposer-2.1.0/bitcomposer/translate/whole/own.py +71 -0
  49. bitcomposer-2.1.0/bitcomposer/translate/whole/plan.py +4873 -0
  50. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/whole/render.py +417 -53
  51. bitcomposer-2.1.0/bitcomposer/translate/whole/settle.py +624 -0
  52. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/writer/__init__.py +2 -2
  53. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/writer/figures.py +10 -4
  54. bitcomposer-2.1.0/bitcomposer/translate/writer/parts.py +1150 -0
  55. bitcomposer-2.1.0/bitcomposer/translate/writer/tune.py +2121 -0
  56. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/writer/upper.py +150 -17
  57. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/vocabularies/__init__.py +2 -2
  58. bitcomposer-2.1.0/bitcomposer/vocabularies/default.json.gz +0 -0
  59. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/written.py +27 -14
  60. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/PKG-INFO +210 -152
  61. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/SOURCES.txt +6 -0
  62. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_arrangement.py +1 -1
  63. bitcomposer-2.1.0/tests/test_lead.py +145 -0
  64. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_library.py +18 -1
  65. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_packfile.py +53 -0
  66. bitcomposer-2.1.0/tests/test_performance.py +179 -0
  67. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_player.py +493 -1
  68. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_score.py +19 -0
  69. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_tables.py +429 -0
  70. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_translate.py +294 -9
  71. bitcomposer-2.1.0/tests/test_whole.py +7068 -0
  72. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_writer.py +1 -1
  73. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_written.py +67 -4
  74. bitcomposer-2.0.0rc2/bitcomposer/translate/reading.py +0 -97
  75. bitcomposer-2.0.0rc2/bitcomposer/translate/rhythm/__init__.py +0 -8
  76. bitcomposer-2.0.0rc2/bitcomposer/translate/rhythm/arrangement.py +0 -1292
  77. bitcomposer-2.0.0rc2/bitcomposer/translate/roles.py +0 -262
  78. bitcomposer-2.0.0rc2/bitcomposer/translate/whole/__init__.py +0 -5
  79. bitcomposer-2.0.0rc2/bitcomposer/translate/whole/plan.py +0 -1373
  80. bitcomposer-2.0.0rc2/bitcomposer/translate/writer/parts.py +0 -588
  81. bitcomposer-2.0.0rc2/bitcomposer/translate/writer/tune.py +0 -1273
  82. bitcomposer-2.0.0rc2/bitcomposer/vocabularies/default.json.gz +0 -0
  83. bitcomposer-2.0.0rc2/tests/test_lead.py +0 -45
  84. bitcomposer-2.0.0rc2/tests/test_whole.py +0 -1367
  85. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/LICENSE +0 -0
  86. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/__main__.py +0 -0
  87. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/arp.py +0 -0
  88. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/bass.py +0 -0
  89. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/builder.py +0 -0
  90. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/drums.py +0 -0
  91. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/echo.py +0 -0
  92. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/harmony.py +0 -0
  93. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/it_format.py +0 -0
  94. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/melody.py +0 -0
  95. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/mix.py +0 -0
  96. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/names.py +0 -0
  97. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/evermore.py +0 -0
  98. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/ffvi.py +0 -0
  99. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/packs/mana.py +0 -0
  100. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/pattern.py +0 -0
  101. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/__init__.py +0 -0
  102. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/__main__.py +0 -0
  103. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/app.py +0 -0
  104. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/audio.py +0 -0
  105. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/autostart.py +0 -0
  106. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/desktop.py +0 -0
  107. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/JetBrainsMono-Bold.ttf +0 -0
  108. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/JetBrainsMono-Regular.ttf +0 -0
  109. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/LICENSE.txt +0 -0
  110. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/OFL-Silkscreen.txt +0 -0
  111. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/Silkscreen-Bold.ttf +0 -0
  112. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/fonts/Silkscreen-Regular.ttf +0 -0
  113. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/mediakeys_win.py +0 -0
  114. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/player/mpris.py +0 -0
  115. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/registers.py +0 -0
  116. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/samples/chip.py +0 -0
  117. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/samples/dsp.py +0 -0
  118. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/samples/genesis.py +0 -0
  119. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/samples/snes.py +0 -0
  120. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/__init__.py +0 -0
  121. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/emulate.py +0 -0
  122. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/it_song.py +0 -0
  123. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/notes.py +0 -0
  124. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/spc/snes_chip.py +0 -0
  125. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/structure.py +0 -0
  126. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/theory.py +0 -0
  127. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/__init__.py +0 -0
  128. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/__main__.py +0 -0
  129. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/against.py +0 -0
  130. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/archives.py +0 -0
  131. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/form.py +0 -0
  132. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/games.py +0 -0
  133. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/harness.py +0 -0
  134. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/measures.py +0 -0
  135. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/phase.py +0 -0
  136. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/reference.py +0 -0
  137. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer/translate/rhythm/form.py +0 -0
  138. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/dependency_links.txt +0 -0
  139. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/entry_points.txt +0 -0
  140. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/requires.txt +0 -0
  141. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/bitcomposer.egg-info/top_level.txt +0 -0
  142. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/pyproject.toml +0 -0
  143. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/setup.cfg +0 -0
  144. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_determinism.py +0 -0
  145. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_format.py +0 -0
  146. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_packs.py +0 -0
  147. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_pattern.py +0 -0
  148. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_samples.py +0 -0
  149. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_spc.py +0 -0
  150. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_spc_check.py +0 -0
  151. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_spc_convert.py +0 -0
  152. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_spc_notes.py +0 -0
  153. {bitcomposer-2.0.0rc2 → bitcomposer-2.1.0}/tests/test_theory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitcomposer
3
- Version: 2.0.0rc2
3
+ Version: 2.1.0
4
4
  Summary: Procedural 16-bit chiptune music generator — creates Impulse Tracker (.it) files
5
5
  Author-email: CatDogBark <catdogbark@pm.me>
6
6
  License-Expression: MIT
@@ -36,29 +36,31 @@ Dynamic: license-file
36
36
  [![Release](https://img.shields.io/github/v/release/CatDogBark/bitComposer)](https://github.com/CatDogBark/bitComposer/releases/latest)
37
37
  ![License](https://img.shields.io/badge/license-MIT-green)
38
38
 
39
- Procedural 16-bit game music. A player that composes the next song as the
40
- current one ends, with a live mixer, on Linux and Windows; a command line
41
- and a generator library underneath, pure Python with no dependencies,
39
+ 16-bit game music, written while you listen. A player that writes the next
40
+ song as the current one ends, with a live mixer, on Linux and Windows; a
41
+ command line and a library underneath, pure Python with no dependencies,
42
42
  writing Impulse Tracker `.it` modules any tracker player reads.
43
43
 
44
- Every run composes a new song: a motif-based melody with call-and-response
45
- phrasing, voice-led harmony, bass, arpeggio and drums, arranged into a form
46
- (verse–chorus, AABA, rondo, through-composed) with a drawn intro, an energy
47
- curve and a real ending, titled after what it drew, between 1:15 and 3:30
48
- long. Seven sounds, picked with `--sound`:
44
+ Since 2.0 every song is written the way game soundtracks are put together:
45
+ drawn whole from a vocabulary of counted habits (how the band is balanced,
46
+ how its figures repeat and vary, where the tune comes back), taken from
47
+ the readings of a soundtrack's songs. The vocabulary that ships was
48
+ learned from Final Fantasy VI's 68 songs, as statistics with none of the
49
+ game's notes or samples. The songs play on bitComposer's own sound set,
50
+ generic instruments synthesised here, on one of Classic's four styled
51
+ sets, or on a game's own samples. More under [What GENERATE
52
+ writes](#what-generate-writes).
49
53
 
50
- - **snes** — sampled-style voices built the way the SNES made sound, through a BRR codec model and the SNES echo.
51
- - **ffvi**, **mana**, **evermore**, **megamanx** — style packs: an instrument set rebuilt from each game's own sound chip (every sample profiled, nothing copied) plus the arrangement habits of its score. Details under [Sounds](#sounds).
52
- - **genesis** — FM bells, brass, organ and bass.
53
- - **chip** — square, pulse and triangle waves. Closest to NES and Game Boy.
54
+ Your own games too: the player's LIBRARY screen reads a game's SPC files
55
+ into a pack of its samples and, with 40 songs or more, a vocabulary of its
56
+ own to write from ([Packs from your games](#packs-from-your-games)).
54
57
 
55
- And packs of your own: the player's LIBRARY screen makes one from a game's
56
- own SPC files, the game's samples as its voices ([Packs from your
57
- games](#packs-from-your-games)).
58
+ The 1.x generator stays as [Classic](#classic), with its own knobs and
59
+ eight sounds, the chip and Genesis palettes among them.
58
60
 
59
- **[Listen in your browser](https://catdogbark.github.io/bitComposer/)** — the actual modules, played live by libopenmpt in WebAssembly: one song per sound, straight from the generator, regenerated with each release.
61
+ **[Listen in your browser](https://catdogbark.github.io/bitComposer/)** — the actual modules, played live by libopenmpt in WebAssembly: five songs from the writer, seeds 1 to 5, and one each from six of Classic's sounds.
60
62
 
61
- **Reproducible, not frozen.** The same seed on the same version gives the same song, byte for byte. A new version may change what a seed draws, and the song message records the version that wrote the file.
63
+ **Reproducible, not frozen.** The same seed on the same version gives the same song, byte for byte. A new version may change what a seed draws; a Classic song's message records the version that wrote it.
62
64
 
63
65
  ## Install
64
66
 
@@ -119,164 +121,90 @@ anything built on libopenmpt.
119
121
  Python 3.10 or newer. The generator has no dependencies; the player's
120
122
  window is Qt (PySide6, installed with the package).
121
123
 
122
- ## Sounds
123
-
124
- A style pack pairs an instrument set with the arrangement habits of the score it imitates. Each is built from the game's SPC snapshots: every sample decoded and profiled, matched to the community's instrument tables where they exist, and re-synthesised; nothing from the games is in the repository.
125
-
126
- - `ffvi`: every voice modelled on the game's own sample bank and named by its instrument table: the chorused string section, flutes in chords, the dark synth lead of Locke and the Returners, trumpet, trombone, oboe, Terra's and Cyan's pan flutes, cello, choir, pipe organ and rock organ, the Aria's soprano, the Battle theme's distortion guitar, piano, harp, picked string, acoustic guitar, tubular bell, xylophone, a bass guitar and a kit of its own (kick, snare, hats, cymbal, timpani, wood block), with ostinato strings, a brass counter-line in the chorus, timpani rolls into sections and the game's short, wet echo.
127
- - `mana`: every voice modelled on the game's own sample bank: a soft slow-breathed flute, bright chorused strings, an 'ah' choir, a high whistle, soft and synth brass, marimba, vibraphone, electric piano, tubular bell, reed, accordion, glass and sine pads, fingered, electric and slap basses and a kit of its own (kick, snare, hats, crash, tom, castanet), with major and pentatonic keys, syncopated harmony, bouncy arps, light swing, the kick and snare set back and the game's one-row echo.
128
- - `evermore`: every voice modelled on the game's own sample bank: a slow bright string swell, a warm pad, a dark pad, a glass bell, a breathy flute, a reed, an "oo" choir, harp, tinker music box, piano, pluck and kalimba, a textured drone and a wind loop, a bass, and a quiet kit (soft kick, frame drum, brushes, hat, cymbal, wood ping), with slow tempos, sustained harmony, a drone bass, sparse or no drums, long linear forms and the game's sparing 80 ms echo.
129
- - `megamanx`: every voice modelled on the game's own sample bank and named by it: a driven, chorused lead guitar, a chugging rhythm guitar on power chords, the overdrive guitar for arps and counter-lines, synth brass, strings, a guitar swell pad, a saw pad, organ, the boomer synth lead, square and bright leads, a hollow wave, a bell synth, an acoustic pluck, the orchestra hit for stabs, slap and synth basses on a riff, and a tight kit, at fast tempos in minor keys with the game's 48 ms slapback echo.
130
-
131
- `--sound` picks a palette or a pack in one word; left to chance, the four packs together weigh as much as plain snes.
132
-
133
- - **snes** — sampled-style voices rendered the way the SNES actually made sound: strings, brass, a formant choir, flute, organ, e-piano, bells, plucks and a gated drum kit at 16 kHz with loop points, passed through a BRR codec model for the grain, with the lead, harmony and arp through an echo modelled on the SNES unit's result: fading, darkening repeats on a beat fraction, drawn per song.
134
- - **genesis** — FM bells, brass, organ and bass.
135
- - **chip** — square, pulse and triangle waves.
136
-
137
- ## What you can steer
138
-
139
- Everything defaults to `random`.
140
-
141
- ```
142
- --sound chip|snes|genesis|ffvi|mana|evermore|megamanx the sound in one word: a palette or a style pack (overrides the two below)
143
- --style chip|snes|genesis sound palette
144
- --pack ffvi|mana|evermore|megamanx|none|random style pack: an instrument set with the habits of the scores it imitates (a pack implies snes)
145
- --pack-file PACK.json a pack as data, with its own voices as WAV files (docs/PACKS.md); overrides --pack and --sound
146
- --echo on|off|random echo (random: 70% of snes songs, never chip or genesis)
147
- --echo-wet light|normal|wet|random how much of the lead, harmony and arp the echo carries
148
- --echo-delay eighth|dotted|quarter|slap|row|random beat fraction between repeats, a 48 ms slap, or one row (random: weighted by tempo)
149
- --echo-stereo bounce|centre|random repeats alternate sides, or sit under their source
150
- --keys moving|home moving: choruses/bridges may change key; home: stay put
151
- --tempo slow|medium|fast 80–110 / 110–140 / 140–180 BPM
152
- --energy chill|normal|intense density and arrangement weight
153
- --scale minor|major|pentatonic
154
- --form standard|aaba|rondo|short|linear
155
- --drum-density sparse|normal|busy --no-fills --swing off|light|heavy
156
- --melody simple|phrased phrased = motif-based, has a hook
157
- --harmony-voicing thin|full two real voices, or three
158
- --harmony-mode stabs|sustain|rhythmic
159
- --bass-weight heavy|medium|light
160
- --lead-shift SEMITONES move the lead's window (negative lowers it); default: the sound's own
161
- --name title|timestamp file naming; --prefix / --suffix add a marker ("(auto) " is the player's)
162
- -s SEED -n COUNT -o FILE -d DIR -v
163
- ```
164
-
165
- Some starting points:
166
-
167
- ```bash
168
- # Overworld — bright, sampled palette with echo
169
- bitcomposer -d out --style snes --scale major --tempo medium --form standard
170
-
171
- # FM boss fight
172
- bitcomposer -d out --style genesis --tempo fast --energy intense --scale minor --drum-density busy --form short
173
-
174
- # Game Boy flavour — square waves, thin harmony, no echo
175
- bitcomposer -d out --style chip --echo off --harmony-voicing thin --bass-weight light --form short
176
-
177
- # Credits roll
178
- bitcomposer -d out --style snes --tempo slow --energy chill --scale major --drum-density sparse --no-fills --form linear
179
- ```
180
-
181
- ## How it works
182
-
183
- 1. Pick a key and a scale weighted toward game music (minor pentatonic, dorian, harmonic minor, mixolydian…), then a progression for it. The tables include borrowed chords and secondary dominants — ♭VII, ♭VI, V/V — not just the diatonic set.
184
- 2. Choose a form and its energy curve; decide which sections repeat. Repeated sections draw the same music from the same seed, so the hook comes back.
185
- 3. Generate a motif (rhythm template plus contour) and vary it per bar in statement/answer pairs. Fourteen rhythm templates, six of them with 16th-note pushes and pickups.
186
- 4. Each four-bar pattern holds a chord timeline; about half the time the back two bars move to a related chord. Melody resolves onto chord tones at each change. Harmony is two or three real voices placed near fixed anchors, so it steps rather than leaps and keeps the chord's third; the anchors are set per voice family (pads low and wide, brass and guitars mid and close), the top voice stays under the lead's line, and a stab holds for as long as the voice needs to speak. Bass and arp follow and rest with the section's energy.
187
- 5. Drums come from one-bar templates by section and density, with fills, retriggered snare rolls and tick-level swing.
188
- 6. Instruments are synthesized per song from the chosen palette and written as samples. SNES voices get attack-then-loop sustain and the BRR treatment.
189
- 7. The echo: held lead notes and phrase endings come back as three fading, darkening repeats, the harmony and arp as lighter ones, each on return channels of their own, drums and bass dry. Everything is written as a 19-channel `.it` with the title and a song message (key, BPM, palette, form, seed, and a `layout:` line naming every channel's role) that trackers display.
190
-
191
- Each song gets a title that reads the song: its scale, sound, energy and
192
- tempo lean the words, so a slow minor Evermore piece and a fast Mega Man X
193
- track are named differently (*Lunar Snow*, *Lighthouse of Steel*, *The
194
- Power Plant of Sparks*).
195
-
196
- ## Measuring instead of guessing
197
-
198
- `tools/analyze.py` parses `.it` files back from disk (stdlib only, independent
199
- of the generator) and scores a batch on the things that correlate with
200
- "sounds like a song": section reuse, motif repetition, rhythmic grid, chord
201
- voicing variety, voice motion, effect vocabulary, drum density.
202
-
203
- ```bash
204
- python3 tools/analyze.py 'out/*.it' # metric table
205
- python3 tools/analyze.py --grid out/song.it # tracker-style pattern dump
206
- ```
207
-
208
- [docs/ANALYSIS.md](docs/ANALYSIS.md) is the story of this project: the
209
- output was once limited by three silent arrangement bugs that nine commits
210
- of ear-checking never caught, and every improvement since has been measured
211
- before and after. Read it before changing the generator.
212
-
213
- Tests:
214
-
215
- ```bash
216
- python3 -m unittest discover -s tests -v
217
- ```
218
-
219
124
  ## What GENERATE writes
220
125
 
221
126
  ```bash
222
127
  bitcomposer -s 7 -v
223
128
  ```
224
129
 
225
- writes a whole song the way the idiom's writer does (`docs/IDIOM.md`): a
130
+ writes a whole song the way the idiom's writer does ([docs/IDIOM.md](docs/IDIOM.md)): a
226
131
  plan for the band, each part's figures bar by bar, a tune with a theme that
227
132
  may come back, and the parts' balance, all drawn from a vocabulary of
228
133
  counted habits, played on bitComposer's own sound set (generic
229
134
  instruments, synthesised here from descriptions and modelled on no game's
230
135
  bank, each fitted to its part by register and speed; `--pack ffvi`,
231
136
  `mana`, `evermore` or `megamanx` borrows one of Classic's styled sets
232
- instead) and rendered through the SNES back end. A seed names one song on
137
+ instead) and rendered through the SNES back end, under the player's
138
+ performance (`bitcomposer/performance.py`): the theme comes back with the
139
+ band, the loop plays twice, the echo and the vibrato on held notes of the tune
140
+ are the vocabulary's own words (FFVI's 0.20 echo at 80 ms, its vibrato on a
141
+ fifth of the tune's held notes). `--bare` writes without
142
+ it, the way the Song Checks do; `--no-carry-theme` and `--no-band-returns`
143
+ turn the two switches off. A seed names one song on
233
144
  every machine. `--carry-theme` draws the tune's phrases again until its
234
145
  theme comes back; `--band-returns` brings the chords, the bass or the
235
- accompaniment back with it. In the player this is GENERATE, with THEME
236
- and RETURNS beside it; Classic, the 1.x generator with its own knobs and
237
- the chip and Genesis sounds, is WRITER: classic in SET (`--classic` on the
238
- command line; the options above the flag are its).
146
+ accompaniment back with it. In the player this is GENERATE on PLAY,
147
+ and WRITE AND PLAY on WRITE, where the two switches and a seed field sit;
148
+ [Classic](#classic), the 1.x generator, is WRITER: CLASSIC (1.X) there
149
+ (`--classic` on the command line).
239
150
 
240
151
  Where the vocabulary comes from, plainly: the shipped one
241
- (`bitcomposer/vocabularies/default.json.gz`, 365 KB) was fitted on the
242
- readings of Final Fantasy VI's 67 songs, the game the writing was
152
+ (`bitcomposer/vocabularies/default.json.gz`, 625 KB) was fitted on the
153
+ readings of Final Fantasy VI's 68 songs, the game the writing was
243
154
  measured against round by round until it held up by ear
244
- (`docs/idiom/phase-4-writing.md`). It is the statistics of how that
155
+ ([docs/idiom/phase-4-writing.md](docs/idiom/phase-4-writing.md)). It is the statistics of how that
245
156
  music is put together, the counts of figures, moves, chord changes and
246
157
  balances, and none of the game's samples or notes; a release check
247
158
  (`tools/copycheck.py`) probes every four-bar window of hundreds of
248
159
  written tunes against the games' phrases and ships nothing that copies
249
- one. It is as far as the writing has gone; vocabularies fitted on more
250
- games follow. Importing a game (below) fits that game's own vocabulary
251
- beside its samples and recounts one over everything you have imported;
252
- SET's FROM row offers each once 40 songs stand behind it
253
- (`--vocabulary pack:NAME`, `--vocabulary library`).
160
+ one. Each written song takes its skeleton from one of those songs, drawn,
161
+ as measured from its reading: its form and bar counts where they fit, its
162
+ tempo within a tenth, which parts play in each section, their levels and
163
+ how busy each line is. None of that song's notes come with it: the notes
164
+ are drawn from the counts over all of them. It is as far as the writing
165
+ has gone; vocabularies fitted on more games follow. Importing a game
166
+ (below) fits that game's own vocabulary beside its samples and recounts
167
+ one over everything you have imported; WRITE offers each under WRITTEN
168
+ FROM once 40 songs stand behind it (`--vocabulary pack:NAME`,
169
+ `--vocabulary library`).
170
+
171
+ Every word in the vocabulary, what it counts and why it exists, is in
172
+ [the vocabulary](docs/idiom/VOCABULARY.md), and [the vocabulary's
173
+ map](docs/idiom/vocabulary-map.md) draws, stage by stage, which words
174
+ condition which.
254
175
 
255
176
  ## Packs from your games
256
177
 
257
- New in 1.2, and early. The player's LIBRARY screen makes a pack from a game's
258
- own music. IMPORT a game's SPC set (a folder of `.spc` files, a zip, or
178
+ The player's LIBRARY screen makes a pack from a game's own
179
+ music. IMPORT a game's SPC set (a folder of `.spc` files, a zip, or
259
180
  snesmusic.org's `.rsn`, a `.rar` or a `.7z`, which 7-Zip or unar on your
260
181
  machine unpacks) and each song is run through an emulator of the SNES sound
261
182
  hardware, read as music (the beat and bar, which voice is the melody, the
262
183
  bass, the chords and the drums, the form) and the soundtrack made into a
263
184
  pack: the samples the game plays each part with most, as its voices, a kit
264
185
  of its drums, and the habits the readings give straight (tempo, major or
265
- minor, how often a song has no drums, the echo). OPEN a pack to hear each
266
- voice in its part, see why it was put there (in how many songs, how many
267
- notes) and move it; USE puts it in SOUND; EXPORT writes it as one zip, and
268
- ADD brings an exported pack, or a pack file, back. Importing a game again
269
- starts its pack fresh.
270
-
271
- A pack carries the game's sound; how a song is arranged is still
272
- bitComposer's own, measured against the game's songs. The next stages
273
- teach the generator to write the way the readings show the composers did
274
- (`docs/TRANSLATOR.md`).
186
+ minor, how often a song has no drums, the echo). SOUNDS shows each voice in
187
+ its part, to hear it, see why it was put there (in how many songs, how
188
+ many notes) and move it; USE ITS SOUNDS plays the next songs on them;
189
+ EXPORT writes the pack as one zip, and ADD A PACK brings an exported pack,
190
+ or a pack file, back. Importing a game again
191
+ starts its pack fresh. A game imported under an earlier version is
192
+ written the new way only once it is imported again: the newer reader
193
+ reads its songs again, and its vocabulary is counted with the words an
194
+ older import lacks.
195
+
196
+ An import also counts the game's own tables into its pack. With 40 songs
197
+ or more behind it the game has a vocabulary of its own: WRITE FROM IT in
198
+ LIBRARY, or its card under WRITE's WRITTEN FROM, writes the next songs the
199
+ way that game's are put together, and a library vocabulary recounted over
200
+ everything you have imported sits beside them (`--vocabulary pack:NAME`,
201
+ `--vocabulary library`). Under 40 songs a fitted vocabulary's drums are
202
+ not yet the game's, so none is offered.
275
203
 
276
204
  The emulator, `bitcomposer-emu`, is a compiled package of its own with a
277
205
  wheel for Linux (x86_64 and aarch64), Windows and macOS, so no toolchain
278
206
  is needed. The Windows build carries it. On Linux,
279
- `pipx install "bitcomposer[import]"` installs both, or the panel's GET THE
207
+ `pipx install "bitcomposer[import]"` installs both, or LIBRARY's GET THE
280
208
  EMULATOR adds it to a player already installed, and UPDATE keeps both
281
209
  current (`pip install "bitcomposer[import]"` elsewhere). Where no wheel
282
210
  matches, it builds from source (Rust; CONTRIBUTING.md has how).
@@ -301,10 +229,21 @@ them stay on your machine, in your data folder
301
229
  `bitcomposer-player` (Linux) and `bitComposer.exe` (Windows) are the same
302
230
  program, an application of four screens under one header:
303
231
 
304
- - **PLAY**: the song playing, its position, the transport, GENERATE, AUTO
305
- (the "radio": the next song is written when this one ends), gain with a
306
- soft limiter, each channel's level as the band, and the songs in the
307
- folder with KEEP. Every song the player writes is provisional
232
+ - **PLAY**: one panel for the song playing (its title with its key, tempo
233
+ and form, MORE for the rest of what its file says), its position, the
234
+ transport, GENERATE and AUTO
235
+ (the "radio": the next song is written when this one ends); gain with a
236
+ soft limiter, WIDTH (the stereo width heard: SPEAKERS plays each voice
237
+ where its song puts it, HEADPHONES pulls the pans toward centre), each
238
+ channel's level as the band, with an M and an S on every part (M mutes
239
+ it, S plays it alone, or with the other parts whose S is lit; a part's
240
+ echo goes with it; for the song playing only, never written into the
241
+ file), and the songs in the
242
+ folder with KEEP. GAIN & WIDTH and the band fold to their headings on a
243
+ click, and the song list takes whatever height the window has left, so
244
+ the songs scroll and the screen over them stays put. Every song plays at one level: the player measures a
245
+ song once and trims it as it plays, so a quiet song and a loud one sit
246
+ side by side (SET → LEVEL turns it off; the files are not changed). Every song the player writes is provisional
308
247
  (`(auto) <Title>.it`, so a file browser sorts them together) and pruned
309
248
  after ten unless kept.
310
249
  - **WRITE**: what the next song is written from (the vocabulary that
@@ -314,15 +253,16 @@ program, an application of four screens under one header:
314
253
  switch at the bottom, with its own knobs (sound, tempo, energy, scale,
315
254
  form, echo, bass, drums, harmony) and presets.
316
255
  - **LIBRARY**: the games you have read. IMPORT reads a game's SPC set
317
- into its sounds and, at 40 songs, its own vocabulary; ADD brings in an
318
- exported pack; each game can lend its sounds, be written from,
256
+ into its sounds and, at 40 songs, its own vocabulary; ADD A PACK brings
257
+ in an exported pack; each game can lend its sounds, be written from,
319
258
  be exported, renamed or deleted.
320
259
  - **SOUNDS**: a game's samples by part, each heard with a click and moved
321
260
  when the reading got it wrong.
322
261
 
323
262
  MIX (a live mixer per channel, with the kit and the echo as buses, and
324
- APPLY to write the mix into the file) and SET (start at login, update
325
- checks, release candidates) open as panels over the screen. The look is
263
+ APPLY to write the mix into the file) and SET (one level for every song,
264
+ start at login, update checks, release candidates) open as panels over
265
+ the screen. The look is
326
266
  the SNES era's own pixels, as styling only: the controls are ordinary
327
267
  controls, the text is text, nothing sits on a fixed grid. The window
328
268
  opens no taller than the screen it lands on (scrolling on a small or
@@ -341,9 +281,127 @@ the release's installer and runs it. A player installed from a release
341
281
  candidate is offered the next candidate; a release player only releases,
342
282
  unless SET → CANDIDATES asks for candidates too.
343
283
 
284
+ ## Classic
285
+
286
+ Classic is the 1.x generator, kept whole in 2.0: WRITER: CLASSIC (1.X) on
287
+ the player's WRITE screen, `--classic` on the command line. It has no
288
+ vocabulary. Every run composes a new song from rules and tables of its
289
+ own: a motif-based melody with call-and-response phrasing, voice-led
290
+ harmony, bass, arpeggio and drums, arranged into a form (verse–chorus,
291
+ AABA, rondo, through-composed) with a drawn intro, an energy curve and a
292
+ real ending, titled after what it drew, between 1:15 and 3:30 long. Eight
293
+ sounds, picked with `--sound`:
294
+
295
+ - **snes** — sampled-style voices built the way the SNES made sound, through a BRR codec model and the SNES echo.
296
+ - **bit** — bitComposer's own sound set, the one the writer plays on by default: generic instruments synthesised here from descriptions, modelled on no game's bank.
297
+ - **ffvi**, **mana**, **evermore**, **megamanx** — style packs: an instrument set rebuilt from each game's own sound chip (every sample profiled, nothing copied) plus the arrangement habits of its score. Details under [Sounds](#sounds).
298
+ - **genesis** — FM bells, brass, organ and bass.
299
+ - **chip** — square, pulse and triangle waves. Closest to NES and Game Boy.
300
+
301
+ ### Sounds
302
+
303
+ A style pack pairs an instrument set with the arrangement habits of the score it imitates. Each is built from the game's SPC snapshots: every sample decoded and profiled, matched to the community's instrument tables where they exist, and re-synthesised; nothing from the games is in the repository.
304
+
305
+ - `ffvi`: every voice modelled on the game's own sample bank and named by its instrument table: the chorused string section, flutes in chords, the dark synth lead of Locke and the Returners, trumpet, trombone, oboe, Terra's and Cyan's pan flutes, cello, choir, pipe organ and rock organ, the Aria's soprano, the Battle theme's distortion guitar, piano, harp, picked string, acoustic guitar, tubular bell, xylophone, a bass guitar and a kit of its own (kick, snare, hats, cymbal, timpani, wood block), with ostinato strings, a brass counter-line in the chorus, timpani rolls into sections and the game's short, wet echo.
306
+ - `mana`: every voice modelled on the game's own sample bank: a soft slow-breathed flute, bright chorused strings, an 'ah' choir, a high whistle, soft and synth brass, marimba, vibraphone, electric piano, tubular bell, reed, accordion, glass and sine pads, fingered, electric and slap basses and a kit of its own (kick, snare, hats, crash, tom, castanet), with major and pentatonic keys, syncopated harmony, bouncy arps, light swing, the kick and snare set back and the game's one-row echo.
307
+ - `evermore`: every voice modelled on the game's own sample bank: a slow bright string swell, a warm pad, a dark pad, a glass bell, a breathy flute, a reed, an "oo" choir, harp, tinker music box, piano, pluck and kalimba, a textured drone and a wind loop, a bass, and a quiet kit (soft kick, frame drum, brushes, hat, cymbal, wood ping), with slow tempos, sustained harmony, a drone bass, sparse or no drums, long linear forms and the game's sparing 80 ms echo.
308
+ - `megamanx`: every voice modelled on the game's own sample bank and named by it: a driven, chorused lead guitar, a chugging rhythm guitar on power chords, the overdrive guitar for arps and counter-lines, synth brass, strings, a guitar swell pad, a saw pad, organ, the boomer synth lead, square and bright leads, a hollow wave, a bell synth, an acoustic pluck, the orchestra hit for stabs, slap and synth basses on a riff, and a tight kit, at fast tempos in minor keys with the game's 48 ms slapback echo.
309
+
310
+ `--sound` picks a palette or a pack in one word; left to chance, the four style packs together weigh as much as plain snes, and bit as much as one of them.
311
+
312
+ - **snes** — sampled-style voices rendered the way the SNES actually made sound: strings, brass, a formant choir, flute, organ, e-piano, bells, plucks and a gated drum kit at 16 kHz with loop points, passed through a BRR codec model for the grain, with the lead, harmony and arp through an echo modelled on the SNES unit's result: fading, darkening repeats on a beat fraction, drawn per song.
313
+ - **genesis** — FM bells, brass, organ and bass.
314
+ - **chip** — square, pulse and triangle waves.
315
+
316
+ ### What you can steer
317
+
318
+ With `--classic`, everything defaults to `random` but `--keys` (moving) and `--lead-shift` (the sound's own). Without it, of these a written song reads only `--pack`, `--pack-file`, `--echo off`, `--name`, `--prefix`, `--suffix` and the last line.
319
+
320
+ ```
321
+ --sound chip|snes|genesis|bit|ffvi|mana|evermore|megamanx the sound in one word: a palette or a style pack (overrides the two below)
322
+ --style chip|snes|genesis sound palette
323
+ --pack bit|ffvi|mana|evermore|megamanx|none|random style pack: an instrument set with the habits of the scores it imitates (a pack implies snes)
324
+ --pack-file PACK.json a pack as data, with its own voices as WAV files (docs/PACKS.md); overrides --pack and --sound
325
+ --echo on|off|random echo (random: 70% of snes songs, never chip or genesis)
326
+ --echo-wet light|normal|wet|random how much of the lead, harmony and arp the echo carries
327
+ --echo-delay eighth|dotted|quarter|slap|row|random beat fraction between repeats, a 48 ms slap, or one row (random: weighted by tempo)
328
+ --echo-stereo bounce|centre|random repeats alternate sides, or sit under their source
329
+ --keys moving|home moving: choruses/bridges may change key; home: stay put
330
+ --tempo slow|medium|fast 80–110 / 110–140 / 140–180 BPM
331
+ --energy chill|normal|intense density and arrangement weight
332
+ --scale minor|major|pentatonic
333
+ --form standard|aaba|rondo|short|linear
334
+ --drum-density sparse|normal|busy --no-fills --swing off|light|heavy
335
+ --melody simple|phrased phrased = motif-based, has a hook
336
+ --harmony-voicing thin|full two real voices, or three
337
+ --harmony-mode stabs|sustain|rhythmic
338
+ --bass-weight heavy|medium|light
339
+ --lead-shift SEMITONES move the lead's window (negative lowers it); default: the sound's own
340
+ --name title|timestamp file naming; --prefix / --suffix add a marker ("(auto) " is the player's)
341
+ -s SEED -n COUNT -o FILE -d DIR -v
342
+ ```
343
+
344
+ Some starting points:
345
+
346
+ ```bash
347
+ # Overworld — bright, sampled palette with echo
348
+ bitcomposer --classic -d out --style snes --scale major --tempo medium --form standard
349
+
350
+ # FM boss fight
351
+ bitcomposer --classic -d out --style genesis --tempo fast --energy intense --scale minor --drum-density busy --form short
352
+
353
+ # Game Boy flavour — square waves, thin harmony, no echo
354
+ bitcomposer --classic -d out --style chip --echo off --harmony-voicing thin --bass-weight light --form short
355
+
356
+ # Credits roll
357
+ bitcomposer --classic -d out --style snes --tempo slow --energy chill --scale major --drum-density sparse --no-fills --form linear
358
+ ```
359
+
360
+ ### How it works
361
+
362
+ 1. Pick a key and a scale weighted toward game music (minor pentatonic, dorian, harmonic minor, mixolydian…), then a progression for it. The tables include borrowed chords and secondary dominants — ♭VII, ♭VI, V/V — not just the diatonic set.
363
+ 2. Choose a form and its energy curve; decide which sections repeat. Repeated sections draw the same music from the same seed, so the hook comes back.
364
+ 3. Generate a motif (rhythm template plus contour) and vary it per bar in statement/answer pairs. Fourteen rhythm templates, six of them with 16th-note pushes and pickups.
365
+ 4. Each four-bar pattern holds a chord timeline; about half the time the back two bars move to a related chord. Melody resolves onto chord tones at each change. Harmony is two or three real voices placed near fixed anchors, so it steps rather than leaps and keeps the chord's third; the anchors are set per voice family (pads low and wide, brass and guitars mid and close), the top voice stays under the lead's line, and a stab holds for as long as the voice needs to speak. Bass and arp follow and rest with the section's energy.
366
+ 5. Drums come from one-bar templates by section and density, with fills, retriggered snare rolls and tick-level swing.
367
+ 6. Instruments are synthesized per song from the chosen palette and written as samples. SNES voices get attack-then-loop sustain and the BRR treatment.
368
+ 7. The echo: held lead notes and phrase endings come back as three fading, darkening repeats, the harmony and arp as lighter ones, each on return channels of their own, drums and bass dry. Everything is written as a 19-channel `.it` with the title and a song message (key, BPM, palette, form, seed, and a `layout:` line naming every channel's role) that trackers display.
369
+
370
+ Each song gets a title that reads the song: its scale, sound, energy and
371
+ tempo lean the words, so a slow minor Evermore piece and a fast Mega Man X
372
+ track are named differently (*Lunar Snow*, *Lighthouse of Steel*, *The
373
+ Power Plant of Sparks*).
374
+
375
+ ## Measuring instead of guessing
376
+
377
+ `tools/analyze.py` parses `.it` files back from disk (stdlib only, independent
378
+ of the generator) and scores a batch on the things that correlate with
379
+ "sounds like a song": section reuse, motif repetition, rhythmic grid, chord
380
+ voicing variety, voice motion, effect vocabulary, drum density.
381
+
382
+ ```bash
383
+ python3 tools/analyze.py 'out/*.it' # metric table
384
+ python3 tools/analyze.py --grid out/song.it # tracker-style pattern dump
385
+ ```
386
+
387
+ [docs/ANALYSIS.md](docs/ANALYSIS.md) is the story of this project: the
388
+ output was once limited by three silent arrangement bugs that nine commits
389
+ of ear-checking never caught, and every improvement since has been measured
390
+ before and after. Read it before changing Classic. The writer has its own
391
+ record: [docs/IDIOM.md](docs/IDIOM.md) for the plan, and [docs/idiom/phase-4-writing.md](docs/idiom/phase-4-writing.md)
392
+ for its rounds, each measured against Final Fantasy VI's own songs and
393
+ most passed by ear. What the written songs do that can sound odd, and why it
394
+ stands, is in [docs/LIMITS.md](docs/LIMITS.md).
395
+
396
+ Tests:
397
+
398
+ ```bash
399
+ python3 -m unittest discover -s tests -v
400
+ ```
401
+
344
402
  ## Windows
345
403
 
346
- Every release carries `bitComposer-setup.exe` (the installer) and `bitComposer-windows.zip` (the same `bitComposer` folder, no install), built by GitHub Actions on every push to main and attached on the tag: `bitComposer.exe`, the player, with Qt, libopenmpt and the SNES emulator (for importing a game's music) beside it; and `bitcomposer-cli.exe`, the command line. The installer installs for your user by default (no administrator prompt; all users is an option on its first page), and the player's UPDATE button runs the next one quietly and reopens the player. Each build also renders the player offscreen at common screen sizes and scalings (1366×768, 1920×1080 at 100% and 150%, 2560×1440 at 125%, 4K at 200%), kept as the workflow's `player-screenshots-windows` artifact. Songs are `.it` files; [OpenMPT](https://openmpt.org) and XMPlay play them too. Windows releases are to be code-signed through the SignPath Foundation's programme for open-source projects (see [Code signing policy](#code-signing-policy)); until that is in place they are unsigned, so SmartScreen asks once ("More info", "Run anyway"). With Python installed instead, `pipx install bitcomposer` gives the same programs as `bitcomposer-player` and `bitcomposer`.
404
+ Every release carries `bitComposer-setup.exe` (the installer) and `bitComposer-windows.zip` (the same `bitComposer` folder, no install), built by GitHub Actions on every pull request into main and attached on the tag: `bitComposer.exe`, the player, with Qt, libopenmpt and the SNES emulator (for importing a game's music) beside it; and `bitcomposer-cli.exe`, the command line. The installer installs for your user by default (no administrator prompt; all users is an option on its first page), and the player's UPDATE button runs the next one quietly and reopens the player. Each build also renders the player offscreen at common screen sizes and scalings (1366×768, 1920×1080 at 100% and 150%, 2560×1440 at 125%, 4K at 200%), kept as the workflow's `player-screenshots-windows` artifact. Songs are `.it` files; [OpenMPT](https://openmpt.org) and XMPlay play them too. Windows releases are to be code-signed through the SignPath Foundation's programme for open-source projects (see [Code signing policy](#code-signing-policy)); until that is in place they are unsigned, so SmartScreen asks once ("More info", "Run anyway"). Smart App Control, where Windows 11 has it on, blocks unsigned programs outright with no such choice; bitComposer runs only with it off (Windows Security, App & browser control). With Python installed instead, `pipx install bitcomposer` gives the same programs as `bitcomposer-player` and `bitcomposer`.
347
405
 
348
406
  ## Code signing policy
349
407
 
@@ -364,7 +422,7 @@ bitComposer composes and plays music on your computer. It collects nothing about
364
422
 
365
423
  One thing goes over the network on its own: when the player starts, it asks GitHub's public releases list (`api.github.com`) whether a newer version exists, so it can offer the UPDATE button. That request carries only what any web request does (your IP address and the program's name), and [GitHub's privacy statement](https://docs.github.com/site-policy/privacy-policies/github-general-privacy-statement) covers it. Turn it off in the player under SET → PLAYER → UPDATES. Updating itself downloads only when you press UPDATE: the installer from GitHub on Windows, the package from PyPI with pipx. GET THE EMULATOR downloads the emulator from PyPI the same way, and only when you press it. Importing a game's music reads your files on your machine and sends nothing.
366
424
 
367
- The [listening page](https://catdogbark.github.io/bitComposer/) is a website: GitHub Pages serves it and Google Fonts serves its font, each under its own privacy policy. It plays the songs in your browser and keeps nothing.
425
+ The [listening page](https://catdogbark.github.io/bitComposer/) is a website: GitHub Pages serves it and Google Fonts serves its fonts, each under its own privacy policy. It plays the songs in your browser and keeps nothing.
368
426
 
369
427
  ## License and contact
370
428