pycodedj 0.5.0__tar.gz → 0.5.1__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.
- {pycodedj-0.5.0 → pycodedj-0.5.1}/CHANGELOG.md +13 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/PKG-INFO +2 -2
- {pycodedj-0.5.0 → pycodedj-0.5.1}/README.ja.md +1 -1
- {pycodedj-0.5.0 → pycodedj-0.5.1}/README.md +1 -1
- {pycodedj-0.5.0 → pycodedj-0.5.1}/docs/manual.html +59 -14
- {pycodedj-0.5.0 → pycodedj-0.5.1}/docs/manual.ja.md +47 -10
- {pycodedj-0.5.0 → pycodedj-0.5.1}/docs/manual.md +47 -10
- pycodedj-0.5.1/examples/club_set.py +107 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/pyproject.toml +1 -1
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/__init__.py +1 -1
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/__main__.py +2 -0
- pycodedj-0.5.0/examples/club_set.py +0 -150
- {pycodedj-0.5.0 → pycodedj-0.5.1}/.github/workflows/workflow.yml +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/.gitignore +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/LICENSE +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/docs/CNAME +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/docs/index.html +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/examples/demo.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/examples/hello_sc.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/examples/sound_showcase.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/sc/synths.scd +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/_loop.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/analyzer.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/block_parser.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/engine.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/mapper.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/osc_bridge.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/pattern.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/src/pycodedj/watcher.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/__init__.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_analyzer.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_block_parser.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_engine.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_mapper.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_osc_bridge.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_pattern.py +0 -0
- {pycodedj-0.5.0 → pycodedj-0.5.1}/tests/test_watcher.py +0 -0
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.1] - 2026-05-08
|
|
4
|
+
|
|
5
|
+
### Improvements
|
|
6
|
+
|
|
7
|
+
- `examples/club_set.py` を `pattern()` / `synth=` ベースの重低音クラブセットに刷新。4つ打ちキック、ランブル、サブ、アシッド、ハット、フィル、空間ノイズを含む 11 ループ構成に変更
|
|
8
|
+
- `pycodedj --version` を追加し、公開前チェックでパッケージバージョンを確認できるようにした
|
|
9
|
+
|
|
10
|
+
### Docs
|
|
11
|
+
|
|
12
|
+
- `docs/manual.ja.md` / `docs/manual.md` / `docs/manual.html` — ループ名と音色名の違いを明確化し、音色は `synth=` で指定することを追記
|
|
13
|
+
- `docs/manual.ja.md` / `docs/manual.md` / `docs/manual.html` — `examples/club_set.py` の重低音クラブセットの使い方と主要レイヤー一覧を追加
|
|
14
|
+
- `README.ja.md` / `README.md` — `examples/club_set.py` の説明を現在の 11 ループ構成に更新
|
|
15
|
+
|
|
3
16
|
## [0.5.0] - 2026-05-08
|
|
4
17
|
|
|
5
18
|
### Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycodedj
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
License: MIT License with Commons Clause
|
|
5
5
|
|
|
6
6
|
"Commons Clause" License Condition v1.0
|
|
@@ -247,7 +247,7 @@ Token reference:
|
|
|
247
247
|
| File | Contents |
|
|
248
248
|
| :--- | :--- |
|
|
249
249
|
| `examples/demo.py` | Intro demo: bass / melody / pad |
|
|
250
|
-
| `examples/club_set.py` |
|
|
250
|
+
| `examples/club_set.py` | Sub-heavy club set: 11 loops with kick, rumble, sub, acid, hats, and room noise |
|
|
251
251
|
| `examples/sound_showcase.py` | All 30 synths — evaluate one at a time to audition |
|
|
252
252
|
|
|
253
253
|
---
|
|
@@ -185,7 +185,7 @@ def chord():
|
|
|
185
185
|
| ファイル | 内容 |
|
|
186
186
|
| :--- | :--- |
|
|
187
187
|
| `examples/demo.py` | bass / melody / pad の 3 ループ入門デモ |
|
|
188
|
-
| `examples/club_set.py` |
|
|
188
|
+
| `examples/club_set.py` | 重低音クラブセット(キック、ランブル、サブ、アシッド、ハット、空間ノイズを含む 11 ループ) |
|
|
189
189
|
| `examples/sound_showcase.py` | 全 30 音色 — 1 音ずつ eval して確認できる |
|
|
190
190
|
|
|
191
191
|
---
|
|
@@ -185,7 +185,7 @@ Token reference:
|
|
|
185
185
|
| File | Contents |
|
|
186
186
|
| :--- | :--- |
|
|
187
187
|
| `examples/demo.py` | Intro demo: bass / melody / pad |
|
|
188
|
-
| `examples/club_set.py` |
|
|
188
|
+
| `examples/club_set.py` | Sub-heavy club set: 11 loops with kick, rumble, sub, acid, hats, and room noise |
|
|
189
189
|
| `examples/sound_showcase.py` | All 30 synths — evaluate one at a time to audition |
|
|
190
190
|
|
|
191
191
|
---
|
|
@@ -808,6 +808,8 @@ def kick_drum():
|
|
|
808
808
|
|
|
809
809
|
<h3>@loop のパラメーター(pattern 用)</h3>
|
|
810
810
|
|
|
811
|
+
<p><strong>音色は <code>synth=</code> で指定します。</strong> <code>@loop("bass", synth="floor_kick")</code> と書くと、ループ名は <code>bass</code> のまま、鳴る音色だけが <code>floor_kick</code> になります。</p>
|
|
812
|
+
|
|
811
813
|
<table>
|
|
812
814
|
<thead><tr><th>引数</th><th>説明</th><th>例</th></tr></thead>
|
|
813
815
|
<tbody>
|
|
@@ -818,6 +820,10 @@ def kick_drum():
|
|
|
818
820
|
</tbody>
|
|
819
821
|
</table>
|
|
820
822
|
|
|
823
|
+
<blockquote>
|
|
824
|
+
<p><code>@loop("kick", synth="floor_kick")</code> の <code>"kick"</code> はループ名、<code>"floor_kick"</code> は音色名です。<code>pycodedj eval demo.py::kick</code> や <code>pycodedj mute kick</code> ではループ名を使います。</p>
|
|
825
|
+
</blockquote>
|
|
826
|
+
|
|
821
827
|
<h3>トリガーパターン — x と . だけで</h3>
|
|
822
828
|
|
|
823
829
|
<p>音程なしで「リズムだけ」を指定したいときは <code>x</code> と <code>.</code> だけ使います。</p>
|
|
@@ -965,9 +971,29 @@ def atmosphere(volume=0.08):
|
|
|
965
971
|
|
|
966
972
|
<pre data-lang="bash"><code id="code-s8-2">pycodedj watch myfile.py</code></pre>
|
|
967
973
|
|
|
974
|
+
<h3>重低音クラブセットを試す</h3>
|
|
975
|
+
|
|
976
|
+
<p><code>examples/club_set.py</code> は、クラブのフロアで鳴る低域を意識したサンプルです。4つ打ちキック、2・4拍のクラップ、オフビートハット、16分ハット、ランブル、サブベース、アシッドベース、スタブ、フィル、空間ノイズを重ねています。</p>
|
|
977
|
+
|
|
978
|
+
<pre data-lang="bash"><code id="code-s8-3">pycodedj watch examples/club_set.py</code></pre>
|
|
979
|
+
|
|
980
|
+
<p>主なループ名は次の通りです。<code>mute</code> / <code>unmute</code> で足し引きすると、クラブトラックのレイヤー構造がわかりやすくなります。</p>
|
|
981
|
+
|
|
982
|
+
<table>
|
|
983
|
+
<thead><tr><th>ループ名</th><th>役割</th><th>音色名</th></tr></thead>
|
|
984
|
+
<tbody>
|
|
985
|
+
<tr><td><code>kick</code></td><td>4つ打ちの土台</td><td><code>floor_kick</code></td></tr>
|
|
986
|
+
<tr><td><code>rumble</code></td><td>床鳴りする低域</td><td><code>bass_rumble</code></td></tr>
|
|
987
|
+
<tr><td><code>sub</code> / <code>floor</code></td><td>持続する重低音</td><td><code>sub_bass</code></td></tr>
|
|
988
|
+
<tr><td><code>acid</code></td><td>動くベースライン</td><td><code>bass_acid</code></td></tr>
|
|
989
|
+
<tr><td><code>offhat</code> / <code>hats</code></td><td>グルーヴの推進力</td><td><code>hat_ride</code>, <code>hat_engine</code></td></tr>
|
|
990
|
+
<tr><td><code>room</code></td><td>倉庫のような空間感</td><td><code>warehouse_air</code></td></tr>
|
|
991
|
+
</tbody>
|
|
992
|
+
</table>
|
|
993
|
+
|
|
968
994
|
<h3>演奏中のコントロール</h3>
|
|
969
995
|
|
|
970
|
-
<pre data-lang="bash"><code id="code-s8-
|
|
996
|
+
<pre data-lang="bash"><code id="code-s8-4">pycodedj mute bass # bass を消音(停止はしない)
|
|
971
997
|
pycodedj unmute bass # bass の音量を元に戻す
|
|
972
998
|
pycodedj panic # すべてのループを即時停止
|
|
973
999
|
pycodedj status # ループの状態を確認</code></pre>
|
|
@@ -980,7 +1006,7 @@ pycodedj status # ループの状態を確認</code></pre>
|
|
|
980
1006
|
<thead><tr><th>ファイル</th><th>内容</th></tr></thead>
|
|
981
1007
|
<tbody>
|
|
982
1008
|
<tr><td><code>examples/demo.py</code></td><td>bass / melody / pad の 3 ループ入門デモ</td></tr>
|
|
983
|
-
<tr><td><code>examples/club_set.py</code></td><td
|
|
1009
|
+
<tr><td><code>examples/club_set.py</code></td><td>重低音クラブセット(キック、ランブル、サブ、アシッド、ハット、空間ノイズを含む 11 ループ)</td></tr>
|
|
984
1010
|
<tr><td><code>examples/sound_showcase.py</code></td><td>全 30 音色 — 1 音ずつ eval して確認できる</td></tr>
|
|
985
1011
|
</tbody>
|
|
986
1012
|
</table>
|
|
@@ -992,16 +1018,35 @@ pycodedj status # ループの状態を確認</code></pre>
|
|
|
992
1018
|
<section id="s9">
|
|
993
1019
|
<h2>9. 音色リファレンス</h2>
|
|
994
1020
|
|
|
995
|
-
<p
|
|
1021
|
+
<p>PyCodeDJ では <strong>ループ名</strong> と <strong>音色名</strong> を分けて考えます。</p>
|
|
1022
|
+
|
|
1023
|
+
<ul>
|
|
1024
|
+
<li>ループ名: <code>@loop("kick", ...)</code> の第一引数。<code>pycodedj eval demo.py::kick</code>、<code>mute</code>、<code>solo</code> などで指定する名前</li>
|
|
1025
|
+
<li>音色名: SuperCollider 側のシンセ名。pattern ループでは <code>synth="floor_kick"</code> のように指定する名前</li>
|
|
1026
|
+
</ul>
|
|
1027
|
+
|
|
1028
|
+
<p>音色を選ぶときは、下の表から音色名を選んで <code>synth=</code> に入れます。たとえば <code>@loop("bass", synth="floor_kick")</code> は、<code>bass</code> というループ名で <code>floor_kick</code> の音色を鳴らします。</p>
|
|
1029
|
+
|
|
1030
|
+
<p><code>pattern()</code> を使う場合は、<code>@loop("kick", synth="floor_kick")</code> のように、短いループ名と具体的な音色名を分けて書けます。</p>
|
|
996
1031
|
|
|
997
|
-
<
|
|
998
|
-
|
|
999
|
-
|
|
1032
|
+
<p><code>pattern()</code> を使わない構造マッピングのループでは、互換性のためにループ名と同じ名前の音色があればそれが使われます。たとえば <code>@loop("bass_acid", interval=0.5)</code> は <code>bass_acid</code> 音色で鳴ります。</p>
|
|
1033
|
+
|
|
1034
|
+
<p>全 30 音色を 1 音ずつ確認したい場合は <code>examples/sound_showcase.py</code> を使います。</p>
|
|
1035
|
+
|
|
1036
|
+
<pre data-lang="bash"><code id="code-s9-1">pycodedj eval examples/sound_showcase.py::floor_kick
|
|
1037
|
+
pycodedj eval examples/sound_showcase.py::bass_acid
|
|
1038
|
+
pycodedj eval examples/sound_showcase.py::acid_lead</code></pre>
|
|
1039
|
+
|
|
1040
|
+
<p><code>examples/sound_showcase.py</code> では試聴しやすいように、ループ名を音色名と同じにしています。通常の pattern ループでは、次のように <code>synth=</code> にこの表の音色名を指定します。</p>
|
|
1041
|
+
|
|
1042
|
+
<pre data-lang="python"><code id="code-s9-2">@loop("kick", synth="floor_kick", dur=0.25)
|
|
1043
|
+
def kick():
|
|
1044
|
+
pattern("x . x .")</code></pre>
|
|
1000
1045
|
|
|
1001
1046
|
<h3>キック</h3>
|
|
1002
1047
|
<table>
|
|
1003
1048
|
<thead>
|
|
1004
|
-
<tr><th
|
|
1049
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1005
1050
|
</thead>
|
|
1006
1051
|
<tbody>
|
|
1007
1052
|
<tr><td><code>kick_hard</code></td><td>硬めでアタックの強いキック</td></tr>
|
|
@@ -1013,7 +1058,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1013
1058
|
<h3>ベース</h3>
|
|
1014
1059
|
<table>
|
|
1015
1060
|
<thead>
|
|
1016
|
-
<tr><th
|
|
1061
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1017
1062
|
</thead>
|
|
1018
1063
|
<tbody>
|
|
1019
1064
|
<tr><td><code>bass_rumble</code></td><td>キック由来の低いランブル</td></tr>
|
|
@@ -1026,7 +1071,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1026
1071
|
<h3>パーカッション</h3>
|
|
1027
1072
|
<table>
|
|
1028
1073
|
<thead>
|
|
1029
|
-
<tr><th
|
|
1074
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1030
1075
|
</thead>
|
|
1031
1076
|
<tbody>
|
|
1032
1077
|
<tr><td><code>hat_engine</code></td><td>クローズ/オープンのハットグリッド</td></tr>
|
|
@@ -1042,7 +1087,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1042
1087
|
<h3>コード・スタブ</h3>
|
|
1043
1088
|
<table>
|
|
1044
1089
|
<thead>
|
|
1045
|
-
<tr><th
|
|
1090
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1046
1091
|
</thead>
|
|
1047
1092
|
<tbody>
|
|
1048
1093
|
<tr><td><code>chord_rave</code></td><td>明るいレイブスタブ</td></tr>
|
|
@@ -1057,7 +1102,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1057
1102
|
<h3>リード・メロディー</h3>
|
|
1058
1103
|
<table>
|
|
1059
1104
|
<thead>
|
|
1060
|
-
<tr><th
|
|
1105
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1061
1106
|
</thead>
|
|
1062
1107
|
<tbody>
|
|
1063
1108
|
<tr><td><code>acid_lead</code></td><td>アシッド系リード</td></tr>
|
|
@@ -1071,7 +1116,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1071
1116
|
<h3>アトモスフィア</h3>
|
|
1072
1117
|
<table>
|
|
1073
1118
|
<thead>
|
|
1074
|
-
<tr><th
|
|
1119
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1075
1120
|
</thead>
|
|
1076
1121
|
<tbody>
|
|
1077
1122
|
<tr><td><code>shimmer_pad</code></td><td>深いシマーパッド</td></tr>
|
|
@@ -1083,7 +1128,7 @@ pycodedj eval examples/sound_showcase.py::bell_rave</code></pre>
|
|
|
1083
1128
|
<h3>FX</h3>
|
|
1084
1129
|
<table>
|
|
1085
1130
|
<thead>
|
|
1086
|
-
<tr><th
|
|
1131
|
+
<tr><th>音色名</th><th>音</th></tr>
|
|
1087
1132
|
</thead>
|
|
1088
1133
|
<tbody>
|
|
1089
1134
|
<tr><td><code>fx_impact</code></td><td>低いインパクト</td></tr>
|
|
@@ -1377,7 +1422,7 @@ pycodedj eval demo.py::pad --sc-port 57200</code></pre>
|
|
|
1377
1422
|
<p><strong>使用例:</strong></p>
|
|
1378
1423
|
|
|
1379
1424
|
<pre data-lang="bash"><code id="code-s12-2">pycodedj watch examples/demo.py
|
|
1380
|
-
pycodedj watch club_set.py --debounce 0.5
|
|
1425
|
+
pycodedj watch examples/club_set.py --debounce 0.5
|
|
1381
1426
|
pycodedj watch myfile.py --sc-host 192.168.1.10</code></pre>
|
|
1382
1427
|
|
|
1383
1428
|
<h3><code>pycodedj panic</code></h3>
|
|
@@ -505,6 +505,8 @@ def kick_drum():
|
|
|
505
505
|
|
|
506
506
|
`pattern()` を使うループでは、`@loop` デコレータに次の引数を追加します。
|
|
507
507
|
|
|
508
|
+
**音色は `synth=` で指定します。** `@loop("bass", synth="floor_kick")` と書くと、ループ名は `bass` のまま、鳴る音色だけが `floor_kick` になります。
|
|
509
|
+
|
|
508
510
|
| 引数 | 説明 | 例 |
|
|
509
511
|
| :--- | :--- | :--- |
|
|
510
512
|
| `synth=` | 使うシンセ名 | `synth="floor_kick"` |
|
|
@@ -513,6 +515,7 @@ def kick_drum():
|
|
|
513
515
|
| `dur=` | 1 ステップの長さ(秒) | `dur=0.25`(16 分音符相当) |
|
|
514
516
|
|
|
515
517
|
> **ポイント:** `volume=` / `eq=` / `interval=` は pattern ループでも引き続き使えます。
|
|
518
|
+
> `@loop("kick", synth="floor_kick")` の `"kick"` はループ名、`"floor_kick"` は音色名です。`pycodedj eval demo.py::kick` や `pycodedj mute kick` ではループ名を使います。
|
|
516
519
|
|
|
517
520
|
### トリガーパターン — x と . だけで
|
|
518
521
|
|
|
@@ -693,6 +696,25 @@ watch で起動すれば、保存するたびに変更したループだけが
|
|
|
693
696
|
pycodedj watch myfile.py
|
|
694
697
|
```
|
|
695
698
|
|
|
699
|
+
### 重低音クラブセットを試す
|
|
700
|
+
|
|
701
|
+
`examples/club_set.py` は、クラブのフロアで鳴る低域を意識したサンプルです。4つ打ちキック、2・4拍のクラップ、オフビートハット、16分ハット、ランブル、サブベース、アシッドベース、スタブ、フィル、空間ノイズを重ねています。
|
|
702
|
+
|
|
703
|
+
```bash
|
|
704
|
+
pycodedj watch examples/club_set.py
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
主なループ名は次の通りです。`mute` / `unmute` で足し引きすると、クラブトラックのレイヤー構造がわかりやすくなります。
|
|
708
|
+
|
|
709
|
+
| ループ名 | 役割 | 音色名 |
|
|
710
|
+
| :--- | :--- | :--- |
|
|
711
|
+
| `kick` | 4つ打ちの土台 | `floor_kick` |
|
|
712
|
+
| `rumble` | 床鳴りする低域 | `bass_rumble` |
|
|
713
|
+
| `sub` / `floor` | 持続する重低音 | `sub_bass` |
|
|
714
|
+
| `acid` | 動くベースライン | `bass_acid` |
|
|
715
|
+
| `offhat` / `hats` | グルーヴの推進力 | `hat_ride`, `hat_engine` |
|
|
716
|
+
| `room` | 倉庫のような空間感 | `warehouse_air` |
|
|
717
|
+
|
|
696
718
|
### 演奏中のコントロール
|
|
697
719
|
|
|
698
720
|
**ミュートとアンミュート**
|
|
@@ -729,7 +751,16 @@ pad muted 0.08 200Hz
|
|
|
729
751
|
|
|
730
752
|
## 9. 音色リファレンス
|
|
731
753
|
|
|
732
|
-
|
|
754
|
+
PyCodeDJ では **ループ名** と **音色名** を分けて考えます。
|
|
755
|
+
|
|
756
|
+
- ループ名: `@loop("kick", ...)` の第一引数。`pycodedj eval demo.py::kick`、`mute`、`solo` などで指定する名前
|
|
757
|
+
- 音色名: SuperCollider 側のシンセ名。pattern ループでは `synth="floor_kick"` のように指定する名前
|
|
758
|
+
|
|
759
|
+
音色を選ぶときは、下の表から音色名を選んで `synth=` に入れます。たとえば `@loop("bass", synth="floor_kick")` は、`bass` というループ名で `floor_kick` の音色を鳴らします。
|
|
760
|
+
|
|
761
|
+
`pattern()` を使う場合は、`@loop("kick", synth="floor_kick")` のように、短いループ名と具体的な音色名を分けて書けます。
|
|
762
|
+
|
|
763
|
+
`pattern()` を使わない構造マッピングのループでは、互換性のためにループ名と同じ名前の音色があればそれが使われます。たとえば `@loop("bass_acid", interval=0.5)` は `bass_acid` 音色で鳴ります。
|
|
733
764
|
|
|
734
765
|
全 30 音色を 1 音ずつ確認したい場合は `examples/sound_showcase.py` を使います。
|
|
735
766
|
|
|
@@ -739,11 +770,17 @@ pycodedj eval examples/sound_showcase.py::bass_acid
|
|
|
739
770
|
pycodedj eval examples/sound_showcase.py::acid_lead
|
|
740
771
|
```
|
|
741
772
|
|
|
742
|
-
`synth=`
|
|
773
|
+
`examples/sound_showcase.py` では試聴しやすいように、ループ名を音色名と同じにしています。通常の pattern ループでは、次のように `synth=` にこの表の音色名を指定します。
|
|
774
|
+
|
|
775
|
+
```python
|
|
776
|
+
@loop("kick", synth="floor_kick", dur=0.25)
|
|
777
|
+
def kick():
|
|
778
|
+
pattern("x . x .")
|
|
779
|
+
```
|
|
743
780
|
|
|
744
781
|
### キック
|
|
745
782
|
|
|
746
|
-
|
|
|
783
|
+
| 音色名 | 音の特徴 |
|
|
747
784
|
| :--- | :--- |
|
|
748
785
|
| `kick_hard` | 硬めでアタックの強いキック |
|
|
749
786
|
| `floor_kick` | 太い四つ打ちキック |
|
|
@@ -751,7 +788,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
751
788
|
|
|
752
789
|
### ベース
|
|
753
790
|
|
|
754
|
-
|
|
|
791
|
+
| 音色名 | 音の特徴 |
|
|
755
792
|
| :--- | :--- |
|
|
756
793
|
| `bass_rumble` | 深い低音ランブル |
|
|
757
794
|
| `bass_reese` | 揺れる Reese 系ベース |
|
|
@@ -760,7 +797,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
760
797
|
|
|
761
798
|
### パーカッション
|
|
762
799
|
|
|
763
|
-
|
|
|
800
|
+
| 音色名 | 音の特徴 |
|
|
764
801
|
| :--- | :--- |
|
|
765
802
|
| `hat_engine` | クローズ/オープンのハットグリッド |
|
|
766
803
|
| `hat_ride` | 長めのライド/オープンハット |
|
|
@@ -772,7 +809,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
772
809
|
|
|
773
810
|
### コード・スタブ
|
|
774
811
|
|
|
775
|
-
|
|
|
812
|
+
| 音色名 | 音の特徴 |
|
|
776
813
|
| :--- | :--- |
|
|
777
814
|
| `chord_rave` | 明るいレイブスタブ |
|
|
778
815
|
| `neon_stab` | ネオン系スタブコード |
|
|
@@ -783,7 +820,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
783
820
|
|
|
784
821
|
### リード・メロディー
|
|
785
822
|
|
|
786
|
-
|
|
|
823
|
+
| 音色名 | 音の特徴 |
|
|
787
824
|
| :--- | :--- |
|
|
788
825
|
| `acid_lead` | アシッド系リード |
|
|
789
826
|
| `lead_hoover` | Hoover 風リード |
|
|
@@ -793,7 +830,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
793
830
|
|
|
794
831
|
### アトモスフィア
|
|
795
832
|
|
|
796
|
-
|
|
|
833
|
+
| 音色名 | 音の特徴 |
|
|
797
834
|
| :--- | :--- |
|
|
798
835
|
| `shimmer_pad` | 深いシマーパッド |
|
|
799
836
|
| `warehouse_air` | 倉庫っぽい空気感 |
|
|
@@ -801,7 +838,7 @@ pycodedj eval examples/sound_showcase.py::acid_lead
|
|
|
801
838
|
|
|
802
839
|
### FX
|
|
803
840
|
|
|
804
|
-
|
|
|
841
|
+
| 音色名 | 音の特徴 |
|
|
805
842
|
| :--- | :--- |
|
|
806
843
|
| `fx_impact` | 低いインパクト |
|
|
807
844
|
| `riser_noise` | ノイズライザー(8 秒でスイープ上昇) |
|
|
@@ -1089,7 +1126,7 @@ pycodedj watch FILE [--sc-host HOST] [--sc-port PORT] [--debounce SECS]
|
|
|
1089
1126
|
|
|
1090
1127
|
```bash
|
|
1091
1128
|
pycodedj watch examples/demo.py
|
|
1092
|
-
pycodedj watch club_set.py --debounce 0.5
|
|
1129
|
+
pycodedj watch examples/club_set.py --debounce 0.5
|
|
1093
1130
|
```
|
|
1094
1131
|
|
|
1095
1132
|
### `pycodedj panic`
|
|
@@ -484,6 +484,8 @@ Tokens are separated by spaces. `"x . x ."` is a 4-step pattern.
|
|
|
484
484
|
|
|
485
485
|
### @loop arguments for pattern mode
|
|
486
486
|
|
|
487
|
+
**Choose the sound with `synth=`.** `@loop("bass", synth="floor_kick")` keeps the loop name as `bass`, but plays the `floor_kick` synth.
|
|
488
|
+
|
|
487
489
|
| Argument | Description | Example |
|
|
488
490
|
| :--- | :--- | :--- |
|
|
489
491
|
| `synth=` | Synth name | `synth="floor_kick"` |
|
|
@@ -492,6 +494,7 @@ Tokens are separated by spaces. `"x . x ."` is a 4-step pattern.
|
|
|
492
494
|
| `dur=` | Step length in seconds | `dur=0.25` (sixteenth note) |
|
|
493
495
|
|
|
494
496
|
> `volume=`, `eq=`, and `interval=` still work alongside pattern arguments.
|
|
497
|
+
> In `@loop("kick", synth="floor_kick")`, `"kick"` is the loop name and `"floor_kick"` is the synth name. Use the loop name for commands such as `pycodedj eval demo.py::kick` and `pycodedj mute kick`.
|
|
495
498
|
|
|
496
499
|
### Trigger patterns — x and . only
|
|
497
500
|
|
|
@@ -670,6 +673,25 @@ Start watching and each save updates only the changed loops:
|
|
|
670
673
|
pycodedj watch myfile.py
|
|
671
674
|
```
|
|
672
675
|
|
|
676
|
+
### Try the sub-heavy club set
|
|
677
|
+
|
|
678
|
+
`examples/club_set.py` is a low-end club-floor example. It layers a four-on-the-floor kick, clap on beats 2 and 4, offbeat hats, 16th-note hats, rumble, sub bass, acid bass, sparse stabs, fills, and room noise.
|
|
679
|
+
|
|
680
|
+
```bash
|
|
681
|
+
pycodedj watch examples/club_set.py
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
These are the main loop names. Use `mute` / `unmute` to bring layers in and out and hear how the groove is built.
|
|
685
|
+
|
|
686
|
+
| Loop name | Role | Synth name |
|
|
687
|
+
| :--- | :--- | :--- |
|
|
688
|
+
| `kick` | Four-on-the-floor foundation | `floor_kick` |
|
|
689
|
+
| `rumble` | Floor-shaking low end | `bass_rumble` |
|
|
690
|
+
| `sub` / `floor` | Sustained sub pressure | `sub_bass` |
|
|
691
|
+
| `acid` | Moving bassline | `bass_acid` |
|
|
692
|
+
| `offhat` / `hats` | Groove and forward motion | `hat_ride`, `hat_engine` |
|
|
693
|
+
| `room` | Warehouse-like space | `warehouse_air` |
|
|
694
|
+
|
|
673
695
|
### Live controls
|
|
674
696
|
|
|
675
697
|
**Mute and unmute**
|
|
@@ -706,7 +728,16 @@ Delete the `@loop` block (decorator + function) and save. In watch mode, the loo
|
|
|
706
728
|
|
|
707
729
|
## 9. Sound Reference
|
|
708
730
|
|
|
709
|
-
|
|
731
|
+
PyCodeDJ has two related names:
|
|
732
|
+
|
|
733
|
+
- Loop name: the first argument to `@loop("kick", ...)`. Use it with `pycodedj eval demo.py::kick`, `mute`, `solo`, and status commands.
|
|
734
|
+
- Synth name: the SuperCollider synth name. Pattern loops set it with `synth="floor_kick"`.
|
|
735
|
+
|
|
736
|
+
To choose a sound, pick a synth name from the tables below and put it in `synth=`. For example, `@loop("bass", synth="floor_kick")` creates a loop called `bass` that plays the `floor_kick` synth.
|
|
737
|
+
|
|
738
|
+
With `pattern()`, you can keep these names separate: `@loop("kick", synth="floor_kick")` means the loop is called `kick`, and it plays the `floor_kick` synth.
|
|
739
|
+
|
|
740
|
+
For non-pattern structure-mapping loops, PyCodeDJ keeps the older shorthand: if the loop name matches a synth name, that synth is used. For example, `@loop("bass_acid", interval=0.5)` plays the `bass_acid` synth.
|
|
710
741
|
|
|
711
742
|
To audition all 30 synths one at a time, use `examples/sound_showcase.py`:
|
|
712
743
|
|
|
@@ -716,11 +747,17 @@ pycodedj eval examples/sound_showcase.py::bass_acid
|
|
|
716
747
|
pycodedj eval examples/sound_showcase.py::acid_lead
|
|
717
748
|
```
|
|
718
749
|
|
|
719
|
-
|
|
750
|
+
In `examples/sound_showcase.py`, loop names intentionally match synth names so each sound is easy to audition. In normal pattern loops, put one of the synth names below in `synth=`:
|
|
751
|
+
|
|
752
|
+
```python
|
|
753
|
+
@loop("kick", synth="floor_kick", dur=0.25)
|
|
754
|
+
def kick():
|
|
755
|
+
pattern("x . x .")
|
|
756
|
+
```
|
|
720
757
|
|
|
721
758
|
### Kick
|
|
722
759
|
|
|
723
|
-
|
|
|
760
|
+
| Synth name | Sound |
|
|
724
761
|
| :--- | :--- |
|
|
725
762
|
| `kick_hard` | Hard, punchy kick |
|
|
726
763
|
| `floor_kick` | Full four-on-the-floor kick |
|
|
@@ -728,7 +765,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
728
765
|
|
|
729
766
|
### Bass
|
|
730
767
|
|
|
731
|
-
|
|
|
768
|
+
| Synth name | Sound |
|
|
732
769
|
| :--- | :--- |
|
|
733
770
|
| `bass_rumble` | Deep low rumble |
|
|
734
771
|
| `bass_reese` | Reese-style wobble bass |
|
|
@@ -737,7 +774,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
737
774
|
|
|
738
775
|
### Percussion
|
|
739
776
|
|
|
740
|
-
|
|
|
777
|
+
| Synth name | Sound |
|
|
741
778
|
| :--- | :--- |
|
|
742
779
|
| `hat_engine` | Closed/open hi-hat grid |
|
|
743
780
|
| `hat_ride` | Long ride/open hat |
|
|
@@ -749,7 +786,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
749
786
|
|
|
750
787
|
### Chords / Stabs
|
|
751
788
|
|
|
752
|
-
|
|
|
789
|
+
| Synth name | Sound |
|
|
753
790
|
| :--- | :--- |
|
|
754
791
|
| `chord_rave` | Bright rave stab |
|
|
755
792
|
| `neon_stab` | Neon-style stab chord |
|
|
@@ -760,7 +797,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
760
797
|
|
|
761
798
|
### Lead / Melody
|
|
762
799
|
|
|
763
|
-
|
|
|
800
|
+
| Synth name | Sound |
|
|
764
801
|
| :--- | :--- |
|
|
765
802
|
| `acid_lead` | Acid-style lead |
|
|
766
803
|
| `lead_hoover` | Hoover-style lead |
|
|
@@ -770,7 +807,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
770
807
|
|
|
771
808
|
### Atmosphere
|
|
772
809
|
|
|
773
|
-
|
|
|
810
|
+
| Synth name | Sound |
|
|
774
811
|
| :--- | :--- |
|
|
775
812
|
| `shimmer_pad` | Deep shimmer pad |
|
|
776
813
|
| `warehouse_air` | Industrial air texture |
|
|
@@ -778,7 +815,7 @@ The same names work with the `synth=` argument in pattern mode.
|
|
|
778
815
|
|
|
779
816
|
### FX
|
|
780
817
|
|
|
781
|
-
|
|
|
818
|
+
| Synth name | Sound |
|
|
782
819
|
| :--- | :--- |
|
|
783
820
|
| `fx_impact` | Low impact hit |
|
|
784
821
|
| `riser_noise` | Noise riser (8-second upward sweep) |
|
|
@@ -1058,7 +1095,7 @@ pycodedj watch FILE [--sc-host HOST] [--sc-port PORT] [--debounce SECS]
|
|
|
1058
1095
|
|
|
1059
1096
|
```bash
|
|
1060
1097
|
pycodedj watch examples/demo.py
|
|
1061
|
-
pycodedj watch club_set.py --debounce 0.5
|
|
1098
|
+
pycodedj watch examples/club_set.py --debounce 0.5
|
|
1062
1099
|
```
|
|
1063
1100
|
|
|
1064
1101
|
### `pycodedj panic`
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# PyCodeDJ club set — sub-heavy warehouse floor
|
|
2
|
+
#
|
|
3
|
+
# Load sc/synths.scd in SuperCollider, then run:
|
|
4
|
+
# pycodedj watch examples/club_set.py
|
|
5
|
+
#
|
|
6
|
+
# Club-focused design:
|
|
7
|
+
# - steady four-on-the-floor kick for dancers
|
|
8
|
+
# - clap on 2 and 4
|
|
9
|
+
# - offbeat hats plus 16th-note motion
|
|
10
|
+
# - bass notes locked to the kick with syncopated replies
|
|
11
|
+
# - sustained sub and rumble layers for floor pressure
|
|
12
|
+
# - sparse stabs and fills so the bass has room
|
|
13
|
+
|
|
14
|
+
from pycodedj import loop, pattern
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# --- Drum engine: stable pulse first, variations second ---
|
|
18
|
+
|
|
19
|
+
@loop("kick", synth="floor_kick", dur=0.117)
|
|
20
|
+
def kick(volume=1.0, eq="edm", low=1.7, mid=0.78, high=0.82):
|
|
21
|
+
pattern(
|
|
22
|
+
"x . . . x . . . x . . . x . . . "
|
|
23
|
+
"x . . . x . . x x . . . x . . x"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@loop("clap", synth="clap_snare", dur=0.117)
|
|
28
|
+
def clap(volume=0.18, eq="pop", low=0.62, mid=0.85, high=0.98):
|
|
29
|
+
pattern(
|
|
30
|
+
". . . . x . . . . . . . x . . . "
|
|
31
|
+
". . . . x . . . . . . x x . x ."
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@loop("offhat", synth="hat_ride", dur=0.117)
|
|
36
|
+
def offhat(volume=0.065, eq="edm", low=0.28, mid=0.78, high=1.0):
|
|
37
|
+
pattern(
|
|
38
|
+
". . x . . . x . . . x . . . x . "
|
|
39
|
+
". . x . . x x . . . x . . x x ."
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@loop("hats", synth="hat_engine", dur=0.0585)
|
|
44
|
+
def hats(volume=0.075, eq="edm", low=0.3, mid=0.82, high=1.02):
|
|
45
|
+
pattern(
|
|
46
|
+
"x . x . x x x . x . x . x x x . "
|
|
47
|
+
"x x x . x . x x x . x x x . x ."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# --- Low end: kick-locked weight with room-shaking sustain ---
|
|
52
|
+
|
|
53
|
+
@loop("rumble", synth="bass_rumble", root="A1", scale="minor", dur=0.117)
|
|
54
|
+
def rumble(volume=0.42, eq="edm", low=1.75, mid=0.58, high=0.32):
|
|
55
|
+
pattern(
|
|
56
|
+
"0 ~ . . 0 ~ . . 0 ~ . . 0 ~ . . "
|
|
57
|
+
"0 ~ . . 3 ~ . . 0 ~ . . 5 3 0 ."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@loop("sub", synth="sub_bass", root="A1", scale="minor", dur=0.117)
|
|
62
|
+
def sub(volume=0.58, eq="edm", low=1.85, mid=0.58, high=0.25):
|
|
63
|
+
pattern(
|
|
64
|
+
"0 ~ . 0 0 ~ . 0 0 ~ 3 . 0 ~ . 0 "
|
|
65
|
+
"0 ~ 0 . 3 ~ . 0 0 ~ 5 . 3 ~ 0 ."
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@loop("floor", synth="sub_bass", root="A1", scale="minor", dur=0.468)
|
|
70
|
+
def floor(volume=0.22, eq="edm", low=1.9, mid=0.45, high=0.2):
|
|
71
|
+
pattern("0 ~ 0 ~ 0 ~ 0 ~")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@loop("acid", synth="bass_acid", root="A1", scale="minor", dur=0.0585)
|
|
75
|
+
def acid(volume=0.15, eq="edm", low=1.15, mid=0.88, high=0.72):
|
|
76
|
+
pattern(
|
|
77
|
+
"0 . 0 . 3 . 0 0 0 . 5 . 3 . 0 . "
|
|
78
|
+
"0 . 0 3 . 5 . 3 0 . 7 . 5 . 3 . "
|
|
79
|
+
"0 3 0 . 5 . 7 . 0 . 5 3 0 . 10 . "
|
|
80
|
+
"0 . 0 . 3 . 0 0 5 . 3 . 0 . 0 ."
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
# --- Hooks and fills: sparse enough to leave room for the bass ---
|
|
85
|
+
|
|
86
|
+
@loop("stabs", synth="chord_rave", root="A2", scale="minor", dur=0.117)
|
|
87
|
+
def stabs(volume=0.095, eq="edm", low=0.55, mid=0.72, high=0.78):
|
|
88
|
+
pattern(
|
|
89
|
+
". . . . [0 2 4] . . . . . . . [3 5 7] . . . "
|
|
90
|
+
". . [5 7 9] . . . . . [0 2 4] . . . [3 5 7] . . ."
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@loop("fill", synth="tom_drum", root="A1", scale="minor", dur=0.0585)
|
|
95
|
+
def fill(volume=0.09, eq="edm", low=1.15, mid=0.72, high=0.5):
|
|
96
|
+
pattern(
|
|
97
|
+
". . . . . . . . . . . . . . . . "
|
|
98
|
+
". . . . . . . . . . 0 . 3 5 7 10"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@loop("room", synth="warehouse_air", root="A1", scale="minor", dur=0.468)
|
|
103
|
+
def room(volume=0.08, eq="edm", low=1.2, mid=0.55, high=0.45):
|
|
104
|
+
# dark concrete reflections
|
|
105
|
+
# low frequency pressure
|
|
106
|
+
# distant system noise
|
|
107
|
+
pattern("0 . . . 0 . 3 . 0 . . . 5 . 3 .")
|
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from . import __version__
|
|
7
8
|
from .block_parser import parse_blocks
|
|
8
9
|
from .engine import Engine
|
|
9
10
|
from .osc_bridge import OscBridge, OscEndpoint, OscError
|
|
@@ -11,6 +12,7 @@ from .osc_bridge import OscBridge, OscEndpoint, OscError
|
|
|
11
12
|
|
|
12
13
|
def _build_parser() -> argparse.ArgumentParser:
|
|
13
14
|
parser = argparse.ArgumentParser(prog="pycodedj")
|
|
15
|
+
parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
|
|
14
16
|
sub = parser.add_subparsers(dest="command")
|
|
15
17
|
|
|
16
18
|
eval_p = sub.add_parser("eval", help="Evaluate a loop block and send OSC parameters")
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
# PyCodeDJ club groove — EDM edition
|
|
2
|
-
#
|
|
3
|
-
# 8 loops, each with a distinct code structure and sonic role.
|
|
4
|
-
# Load sc/synths.scd in SuperCollider, then run:
|
|
5
|
-
# pycodedj watch examples/club_set.py
|
|
6
|
-
#
|
|
7
|
-
# Code structure → sound (by design):
|
|
8
|
-
#
|
|
9
|
-
# kick_hard depth=1, cf=0 → 580 Hz, 0.10 Hz LFO (dark, static)
|
|
10
|
-
# sub_bass depth=2, cf=1 → 960 Hz, 0.59 Hz LFO (dark sub pulse)
|
|
11
|
-
# bass_acid depth=5, cf=4 → 2100 Hz, 2.06 Hz LFO (acid squelch)
|
|
12
|
-
# hat_engine depth=7, cf=9 → 2860 Hz, 4.51 Hz LFO (brightest, fastest)
|
|
13
|
-
# clap_snare depth=6, cf=5 → 2480 Hz, 2.55 Hz LFO (bright backbeat)
|
|
14
|
-
# chord_rave depth=7, cf=7 → 2860 Hz, 3.53 Hz LFO (rave stabs)
|
|
15
|
-
# lead_hoover depth=5, cf=4 → 2100 Hz, 2.06 Hz LFO reverb=0.15
|
|
16
|
-
# shimmer_pad depth=1, cf=0 → 580 Hz, 0.10 Hz LFO reverb=0.60
|
|
17
|
-
|
|
18
|
-
from pycodedj import loop
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# --- Foundation: dead simple, bone-dry ---
|
|
22
|
-
|
|
23
|
-
@loop("kick_hard", interval=1.0)
|
|
24
|
-
def four_on_floor(volume=0.9, eq="edm", low=1.25):
|
|
25
|
-
hit = "down"
|
|
26
|
-
_ = hit
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
# --- Sub: minimal pulse, barely more than the kick ---
|
|
30
|
-
|
|
31
|
-
@loop("sub_bass", interval=1.0)
|
|
32
|
-
def sub_layer(volume=0.4, eq="edm", low=1.45, high=0.7):
|
|
33
|
-
for beat in range(4):
|
|
34
|
-
sub = "low"
|
|
35
|
-
_ = sub
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
# --- Groove: syncopated acid sequence with accents ---
|
|
39
|
-
|
|
40
|
-
@loop("bass_acid", interval=0.5)
|
|
41
|
-
def acid_line(volume=0.22, eq="edm", low=1.2, mid=1.05):
|
|
42
|
-
pattern = [
|
|
43
|
-
("hit", True), ("skip", False), ("slide", True),
|
|
44
|
-
("hit", True), ("skip", False), ("accent", True),
|
|
45
|
-
("skip", False), ("slide", True),
|
|
46
|
-
]
|
|
47
|
-
for step, (note, active) in enumerate(pattern):
|
|
48
|
-
if active:
|
|
49
|
-
for layer in range(2):
|
|
50
|
-
if layer == 0:
|
|
51
|
-
out = note
|
|
52
|
-
else:
|
|
53
|
-
out = f"{note}_tail"
|
|
54
|
-
_ = out
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# --- Hats: mechanical 16th-note grid ---
|
|
58
|
-
|
|
59
|
-
@loop("hat_engine", interval=0.25)
|
|
60
|
-
def closed_hats(volume=0.13, eq="edm", low=0.45, high=1.25):
|
|
61
|
-
for bar in range(2):
|
|
62
|
-
for tick in range(16):
|
|
63
|
-
if tick % 4 == 0:
|
|
64
|
-
if tick == 0:
|
|
65
|
-
if bar == 0:
|
|
66
|
-
hat = "anchor_a"
|
|
67
|
-
else:
|
|
68
|
-
hat = "anchor_b"
|
|
69
|
-
else:
|
|
70
|
-
hat = "beat"
|
|
71
|
-
elif tick % 2 == 0:
|
|
72
|
-
hat = "up"
|
|
73
|
-
elif tick in (3, 7, 11, 15):
|
|
74
|
-
if bar == 0:
|
|
75
|
-
hat = "ghost_a"
|
|
76
|
-
else:
|
|
77
|
-
hat = "ghost_b"
|
|
78
|
-
else:
|
|
79
|
-
hat = "skip"
|
|
80
|
-
if tick in (6, 14):
|
|
81
|
-
hat = "open"
|
|
82
|
-
_ = hat
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# --- Backbeat: decisive 2 & 4 with fill on bar 4 ---
|
|
86
|
-
|
|
87
|
-
@loop("clap_snare", interval=1.0)
|
|
88
|
-
def backbeat(volume=0.26, eq="pop", low=0.75, high=1.15):
|
|
89
|
-
for bar in range(4):
|
|
90
|
-
for beat in range(4):
|
|
91
|
-
if beat == 1:
|
|
92
|
-
hit = "snap"
|
|
93
|
-
elif beat == 3:
|
|
94
|
-
if bar == 3:
|
|
95
|
-
hit = "fill"
|
|
96
|
-
else:
|
|
97
|
-
hit = "heavy"
|
|
98
|
-
else:
|
|
99
|
-
hit = "off"
|
|
100
|
-
_ = hit
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# --- Harmonic: stacked chord voices across phrases ---
|
|
104
|
-
|
|
105
|
-
@loop("chord_rave", interval=2.0)
|
|
106
|
-
def rave_stabs(volume=0.14, eq="edm", mid=0.9):
|
|
107
|
-
for phrase in range(4):
|
|
108
|
-
for voice in range(3):
|
|
109
|
-
for harmonic in range(2):
|
|
110
|
-
if phrase == 0:
|
|
111
|
-
if voice == 0:
|
|
112
|
-
chord = "root"
|
|
113
|
-
elif voice == 1:
|
|
114
|
-
chord = "fifth"
|
|
115
|
-
else:
|
|
116
|
-
chord = "octave"
|
|
117
|
-
elif phrase == 2:
|
|
118
|
-
chord = "resolve"
|
|
119
|
-
else:
|
|
120
|
-
chord = "hit"
|
|
121
|
-
_ = chord
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# --- Lead: phrase-based, slight air ---
|
|
125
|
-
|
|
126
|
-
@loop("lead_hoover", interval=4.0)
|
|
127
|
-
def hoover(volume=0.11, eq="edm", high=1.25):
|
|
128
|
-
# classic rave swell
|
|
129
|
-
# builds and drops
|
|
130
|
-
for phrase in range(4):
|
|
131
|
-
for step in range(3):
|
|
132
|
-
if phrase in (0, 2):
|
|
133
|
-
if step == 0:
|
|
134
|
-
motion = "attack"
|
|
135
|
-
else:
|
|
136
|
-
motion = "hold"
|
|
137
|
-
_ = motion
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
# --- Space: pure atmosphere, no code at all ---
|
|
141
|
-
|
|
142
|
-
@loop("shimmer_pad", interval=8.0)
|
|
143
|
-
def shimmer(volume=0.06, eq="acoustic", low=0.65):
|
|
144
|
-
# wide hall reverb
|
|
145
|
-
# slow harmonic drift
|
|
146
|
-
# always underneath everything
|
|
147
|
-
# never noticed until it stops
|
|
148
|
-
# consonance without definition
|
|
149
|
-
# air between the notes
|
|
150
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|