pycodedj 0.1.3__tar.gz → 0.2.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 (37) hide show
  1. {pycodedj-0.1.3 → pycodedj-0.2.0}/.gitignore +3 -1
  2. {pycodedj-0.1.3 → pycodedj-0.2.0}/CHANGELOG.md +33 -0
  3. {pycodedj-0.1.3 → pycodedj-0.2.0}/PKG-INFO +39 -28
  4. {pycodedj-0.1.3 → pycodedj-0.2.0}/README.ja.md +38 -27
  5. {pycodedj-0.1.3 → pycodedj-0.2.0}/README.md +38 -27
  6. {pycodedj-0.1.3 → pycodedj-0.2.0}/docs/index.html +58 -46
  7. {pycodedj-0.1.3 → pycodedj-0.2.0}/docs/manual.ja.md +349 -179
  8. {pycodedj-0.1.3 → pycodedj-0.2.0}/docs/manual.md +350 -174
  9. pycodedj-0.2.0/examples/club_set.py +218 -0
  10. {pycodedj-0.1.3 → pycodedj-0.2.0}/examples/demo.py +14 -9
  11. {pycodedj-0.1.3 → pycodedj-0.2.0}/examples/hello_sc.py +1 -1
  12. {pycodedj-0.1.3 → pycodedj-0.2.0}/pyproject.toml +1 -5
  13. pycodedj-0.2.0/sc/synths.scd +494 -0
  14. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/__init__.py +4 -1
  15. pycodedj-0.2.0/src/pycodedj/_loop.py +9 -0
  16. pycodedj-0.2.0/src/pycodedj/block_parser.py +72 -0
  17. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/engine.py +1 -1
  18. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/mapper.py +5 -1
  19. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/osc_bridge.py +17 -9
  20. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/watcher.py +5 -0
  21. pycodedj-0.2.0/tests/test_block_parser.py +116 -0
  22. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/test_mapper.py +10 -0
  23. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/test_osc_bridge.py +5 -9
  24. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/test_watcher.py +28 -16
  25. pycodedj-0.1.3/docs/visualizer-concept.html +0 -438
  26. pycodedj-0.1.3/examples/club_set.py +0 -71
  27. pycodedj-0.1.3/sc/synths.scd +0 -151
  28. pycodedj-0.1.3/src/pycodedj/block_parser.py +0 -45
  29. pycodedj-0.1.3/tests/test_block_parser.py +0 -66
  30. {pycodedj-0.1.3 → pycodedj-0.2.0}/.github/workflows/workflow.yml +0 -0
  31. {pycodedj-0.1.3 → pycodedj-0.2.0}/LICENSE +0 -0
  32. {pycodedj-0.1.3 → pycodedj-0.2.0}/docs/CNAME +0 -0
  33. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/__main__.py +0 -0
  34. {pycodedj-0.1.3 → pycodedj-0.2.0}/src/pycodedj/analyzer.py +0 -0
  35. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/__init__.py +0 -0
  36. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/test_analyzer.py +0 -0
  37. {pycodedj-0.1.3 → pycodedj-0.2.0}/tests/test_engine.py +0 -0
@@ -50,9 +50,10 @@ logs/
50
50
  .claude/settings.local.json
51
51
  .claude/todos/
52
52
  .claude/mcp*.json
53
- .codex
53
+ .codex/
54
54
  .claude/
55
55
  AGENT.md
56
+ .agents/
56
57
 
57
58
  # Claude Code
58
59
  CLAUDE.local.md
@@ -77,3 +78,4 @@ runs/
77
78
  tmp/
78
79
  temp/
79
80
  .cache/
81
+ docs/visualizer-*.html
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.0] - 2026-05-08
4
+
5
+ ### Breaking
6
+
7
+ - `# @loop <name> interval=<sec>` コメント構文を廃止。`@loop("name", interval=sec)` デコレータ構文に移行
8
+ - 既存のライブコーディングファイルはデコレータ構文への書き換えが必要
9
+
10
+ ### Features
11
+
12
+ - `@loop("name", interval=sec)` デコレータ — ファイルをそのまま `python` で実行できる no-op デコレータとして `from pycodedj import loop` で提供
13
+ - `volume=` 引数 — ループ関数のデフォルト引数として音量を直接指定できる(例: `def my_loop(volume=0.4):`)
14
+ - Amplitude パラメーター(`amp`)を OSC で SuperCollider に送出。`/pycodedj/loop/<name>/params` は `voice_count, cutoff, lfo_rate, reverb, amp` の 5 値に拡張
15
+
16
+ ### Improvements
17
+
18
+ - `sc/synths.scd` — `amp` パラメーターをすべての SynthDef と OSC ハンドラーに追加
19
+ - `examples/club_set.py` — 6 層 14 ループ構成のクラブセットに刷新(foundation / movement / body / harmonic / space / texture)
20
+ - `examples/demo.py` — 新デコレータ構文に更新
21
+
22
+ ### Docs
23
+
24
+ - README.md / README.ja.md — 新デコレータ構文・`volume=` 引数・`amp` OSC パラメーターに全面更新
25
+ - `docs/manual.md` / `docs/manual.ja.md` — 同上
26
+ - `docs/index.html` — ライブデモアニメーションとコード例を新構文に更新
27
+
28
+ ## [0.1.4] - 2026-05-07
29
+
30
+ ### Fixes
31
+
32
+ - Fix editable installs so `pycodedj.__main__` resolves from `src/pycodedj`
33
+ - Fix SuperCollider OSC receiving and address parsing for `/pycodedj/loop/<name>/<param>` messages
34
+ - Keep the SuperCollider OSC receiver active across repeated `synths.scd` reloads
35
+
3
36
  ## [0.1.3] - 2026-05-07
4
37
 
5
38
  ### Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycodedj
3
- Version: 0.1.3
3
+ Version: 0.2.0
4
4
  License: MIT License with Commons Clause
5
5
 
6
6
  "Commons Clause" License Condition v1.0
@@ -62,7 +62,7 @@ Description-Content-Type: text/markdown
62
62
 
63
63
  # PyCodeDJ
64
64
 
65
- [日本語版 README はこちら](https://github.com/kanekoyuichi/pycodedj/blob/main/README.ja.md)
65
+ [日本語版 README はこちら](https://github.com/kanekoyuichi/pycodedj/blob/main/README.ja.md) · [Full Manual (EN)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.md) · [マニュアル (JA)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.ja.md)
66
66
 
67
67
  A live-coding environment that translates Python code structure into music in real time. Every save changes the performance.
68
68
 
@@ -107,6 +107,7 @@ BPM clock is held by SuperCollider's `TempoClock`. Python only sends parameter u
107
107
  | Control-flow count (if/for/while) | LFO rate (0.1–5.0 Hz) | More branches = faster modulation |
108
108
  | Function definition count | Polyphony voice count (1–4) | Functions = independent voices |
109
109
  | Comment ratio | Reverb depth (0.0–0.8) | More whitespace = more space |
110
+ | `volume=` argument | Amplitude (0.0–1.0) | Direct performer control over loudness |
110
111
 
111
112
  Tempo (BPM) and root pitch are controlled explicitly by the performer, to prevent the foundation of the piece from shifting on every save.
112
113
 
@@ -144,20 +145,22 @@ Open `sc/synths.scd` in the SuperCollider IDE and evaluate it.
144
145
  **2. Write a live-coding file**
145
146
 
146
147
  ```python
147
- # @loop bass interval=2.0
148
- def bass():
148
+ from pycodedj import loop
149
+
150
+ @loop("bass", interval=2.0)
151
+ def bass(volume=0.4):
149
152
  for i in range(8):
150
153
  if i % 2 == 0:
151
154
  pass
152
155
 
153
- # @loop melody interval=0.5
154
- def melody():
156
+ @loop("melody", interval=0.5)
157
+ def melody(volume=0.3):
155
158
  x = 1
156
159
  y = 2
157
160
  return x + y
158
161
 
159
- # @loop pad interval=4.0
160
- def pad():
162
+ @loop("pad", interval=4.0)
163
+ def pad(volume=0.15):
161
164
  # make space
162
165
  # a little more
163
166
  pass
@@ -172,7 +175,7 @@ pycodedj eval demo.py::bass
172
175
  On success, feedback is printed immediately:
173
176
 
174
177
  ```
175
- [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1
178
+ [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1 amp=0.40
176
179
  ```
177
180
 
178
181
  Other loops keep playing without interruption.
@@ -187,8 +190,6 @@ pycodedj watch demo.py
187
190
 
188
191
  From here, just write code and save.
189
192
 
190
- > **Note on `interval` (current MVP):** Values like `interval=2.0` are parsed and stored, but are not yet sent over OSC. Loop repeat timing is managed by SuperCollider's `TempoClock`. A mechanism to pass interval to SC is planned for a future release.
191
-
192
193
  ---
193
194
 
194
195
  ## Example Files
@@ -196,7 +197,7 @@ From here, just write code and save.
196
197
  | File | Contents |
197
198
  | :--- | :--- |
198
199
  | `examples/demo.py` | Intro demo with bass / melody / pad |
199
- | `examples/club_set.py` | Club-style demo: sub_bass / hat_engine / neon_stab / acid_lead / warehouse_air |
200
+ | `examples/club_set.py` | Layered club groove using kick_hard / bass_rumble / bass_reese and more |
200
201
 
201
202
  ---
202
203
 
@@ -205,8 +206,10 @@ From here, just write code and save.
205
206
  ### Deeper nesting opens the filter
206
207
 
207
208
  ```python
208
- # @loop bass interval=2.0
209
- def bass():
209
+ from pycodedj import loop
210
+
211
+ @loop("bass", interval=2.0)
212
+ def bass(volume=0.4):
210
213
  for i in range(4): # control flow +1
211
214
  for j in range(4): # depth +1, control flow +1
212
215
  if i == j: # depth +1, control flow +1
@@ -216,21 +219,27 @@ def bass():
216
219
  ### More functions = more polyphony
217
220
 
218
221
  ```python
219
- # @loop chord interval=1.0
220
- def voice_a(): pass
221
- def voice_b(): pass
222
- def voice_c(): pass
223
- def voice_d(): pass
222
+ from pycodedj import loop
223
+
224
+ @loop("chord", interval=1.0)
225
+ def chord(volume=0.2):
226
+ def voice_a(): pass
227
+ def voice_b(): pass
228
+ def voice_c(): pass
229
+ def voice_d(): pass
224
230
  ```
225
231
 
226
232
  ### More comments = more space (reverb)
227
233
 
228
234
  ```python
229
- # @loop pad interval=4.0
230
- # leave space here
231
- # a little more
232
- # silence is music
233
- def pad(): pass
235
+ from pycodedj import loop
236
+
237
+ @loop("pad", interval=4.0)
238
+ def pad(volume=0.15):
239
+ # leave space here
240
+ # a little more
241
+ # silence is music
242
+ pass
234
243
  ```
235
244
 
236
245
  ---
@@ -241,10 +250,12 @@ Addresses used to communicate with SuperCollider.
241
250
 
242
251
  | Address | Type | Range | Parameter |
243
252
  | :--- | :--- | :--- | :--- |
244
- | `/pycodedj/loop/<name>/cutoff` | float | 200–4000 Hz | Filter Cutoff |
245
- | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO rate |
246
- | `/pycodedj/loop/<name>/reverb` | float | 0.0–0.8 | Reverb depth |
247
- | `/pycodedj/loop/<name>/voice_count` | int | 14 | Polyphony voice count |
253
+ | `/pycodedj/loop/<name>/params` | int, float, float, float, float | see parameter order | `voice_count`, `cutoff`, `lfo_rate`, `reverb`, `amp` |
254
+ | `/pycodedj/loop/<name>/cutoff` | float | 2004000 Hz | Filter Cutoff (compatibility) |
255
+ | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO rate (compatibility) |
256
+ | `/pycodedj/loop/<name>/reverb` | float | 0.00.8 | Reverb depth (compatibility) |
257
+ | `/pycodedj/loop/<name>/voice_count` | int | 1–4 | Polyphony voice count (compatibility) |
258
+ | `/pycodedj/loop/<name>/amp` | float | 0.0–1.0 | Amplitude (compatibility) |
248
259
 
249
260
  `<name>` is the loop name (e.g. `bass`, `melody`). Each loop has its own address namespace, so multiple loops never overwrite each other's parameters.
250
261
 
@@ -1,6 +1,6 @@
1
1
  # PyCodeDJ
2
2
 
3
- [English README](https://github.com/kanekoyuichi/pycodedj/blob/main/README.md)
3
+ [English README](https://github.com/kanekoyuichi/pycodedj/blob/main/README.md) · [マニュアル (JA)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.ja.md) · [Full Manual (EN)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.md)
4
4
 
5
5
  Pythonコードの構造をリアルタイムに音楽へ変換するライブコーディング環境。ファイルを保存するたびに演奏が変わる。
6
6
 
@@ -45,6 +45,7 @@ BPMクロックは SuperCollider 側の `TempoClock` が保持します。Python
45
45
  | 制御フロー数(if/for/while) | LFO レート (0.1–5.0 Hz) | 分岐の多さ=揺らぎの速さ |
46
46
  | 関数定義数 | ポリフォニー声部数 (1–4) | 関数=独立した声部 |
47
47
  | コメント率 | リバーブ Depth (0.0–0.8) | 余白の多さ=空間の広さ |
48
+ | `volume=` 引数 | Amplitude (0.0–1.0) | 演奏者が直接音量を制御する |
48
49
 
49
50
  テンポ(BPM)と基音(Pitch)は演奏者が明示的に制御します。保存のたびに楽曲全体の土台が変わることを防ぐためです。
50
51
 
@@ -82,20 +83,22 @@ SuperCollider IDE で `sc/synths.scd` を開いて実行します。
82
83
  **2. ライブコーディングファイルを用意する**
83
84
 
84
85
  ```python
85
- # @loop bass interval=2.0
86
- def bass():
86
+ from pycodedj import loop
87
+
88
+ @loop("bass", interval=2.0)
89
+ def bass(volume=0.4):
87
90
  for i in range(8):
88
91
  if i % 2 == 0:
89
92
  pass
90
93
 
91
- # @loop melody interval=0.5
92
- def melody():
94
+ @loop("melody", interval=0.5)
95
+ def melody(volume=0.3):
93
96
  x = 1
94
97
  y = 2
95
98
  return x + y
96
99
 
97
- # @loop pad interval=4.0
98
- def pad():
100
+ @loop("pad", interval=4.0)
101
+ def pad(volume=0.15):
99
102
  # 空間を作る
100
103
  # もう少し余白
101
104
  pass
@@ -110,7 +113,7 @@ pycodedj eval demo.py::bass
110
113
  成功すると次のフィードバックが表示されます。
111
114
 
112
115
  ```
113
- [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1
116
+ [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1 amp=0.40
114
117
  ```
115
118
 
116
119
  他のループはそのまま鳴り続けます。
@@ -125,8 +128,6 @@ pycodedj watch demo.py
125
128
 
126
129
  あとはエディタでコードを書いて保存するだけです。
127
130
 
128
- > **`interval` について(現在の MVP):** `interval=2.0` のような値はパーサーが読み取りますが、現時点では OSC では送信されません。ループの繰り返し周期は SuperCollider 側の `TempoClock` で管理します。将来的に SC 側に interval を渡す仕組みを追加する予定です。
129
-
130
131
  ---
131
132
 
132
133
  ## サンプルファイル
@@ -134,7 +135,7 @@ pycodedj watch demo.py
134
135
  | ファイル | 内容 |
135
136
  | :--- | :--- |
136
137
  | `examples/demo.py` | bass / melody / pad の 3 ループ入門デモ |
137
- | `examples/club_set.py` | sub_bass / hat_engine / neon_stab / acid_lead / warehouse_air のクラブスタイルデモ |
138
+ | `examples/club_set.py` | kick_hard / bass_rumble / bass_reese などを重ねた多層クラブグルーヴ |
138
139
 
139
140
  ---
140
141
 
@@ -143,8 +144,10 @@ pycodedj watch demo.py
143
144
  ### ネストを深くするとフィルターが開く
144
145
 
145
146
  ```python
146
- # @loop bass interval=2.0
147
- def bass():
147
+ from pycodedj import loop
148
+
149
+ @loop("bass", interval=2.0)
150
+ def bass(volume=0.4):
148
151
  for i in range(4): # 制御フロー +1
149
152
  for j in range(4): # ネスト深さ +1、制御フロー +1
150
153
  if i == j: # ネスト深さ +1、制御フロー +1
@@ -154,21 +157,27 @@ def bass():
154
157
  ### 関数を増やすとポリフォニーが広がる
155
158
 
156
159
  ```python
157
- # @loop chord interval=1.0
158
- def voice_a(): pass
159
- def voice_b(): pass
160
- def voice_c(): pass
161
- def voice_d(): pass
160
+ from pycodedj import loop
161
+
162
+ @loop("chord", interval=1.0)
163
+ def chord(volume=0.2):
164
+ def voice_a(): pass
165
+ def voice_b(): pass
166
+ def voice_c(): pass
167
+ def voice_d(): pass
162
168
  ```
163
169
 
164
170
  ### コメントを増やすと空間(リバーブ)が広がる
165
171
 
166
172
  ```python
167
- # @loop pad interval=4.0
168
- # ここに余白を置く
169
- # もう少し置く
170
- # 静寂も音楽
171
- def pad(): pass
173
+ from pycodedj import loop
174
+
175
+ @loop("pad", interval=4.0)
176
+ def pad(volume=0.15):
177
+ # ここに余白を置く
178
+ # もう少し置く
179
+ # 静寂も音楽
180
+ pass
172
181
  ```
173
182
 
174
183
  ---
@@ -179,10 +188,12 @@ SuperCollider との通信に使うアドレスです。
179
188
 
180
189
  | アドレス | 型 | 値域 | 対応パラメーター |
181
190
  | :--- | :--- | :--- | :--- |
182
- | `/pycodedj/loop/<name>/cutoff` | float | 200–4000 Hz | フィルター Cutoff |
183
- | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO レート |
184
- | `/pycodedj/loop/<name>/reverb` | float | 0.0–0.8 | リバーブ Depth |
185
- | `/pycodedj/loop/<name>/voice_count` | int | 14 | ポリフォニー声部数 |
191
+ | `/pycodedj/loop/<name>/params` | int, float, float, float, float | パラメーター順を参照 | `voice_count`, `cutoff`, `lfo_rate`, `reverb`, `amp` |
192
+ | `/pycodedj/loop/<name>/cutoff` | float | 2004000 Hz | フィルター Cutoff(互換用) |
193
+ | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO レート(互換用) |
194
+ | `/pycodedj/loop/<name>/reverb` | float | 0.00.8 | リバーブ Depth(互換用) |
195
+ | `/pycodedj/loop/<name>/voice_count` | int | 1–4 | ポリフォニー声部数(互換用) |
196
+ | `/pycodedj/loop/<name>/amp` | float | 0.0–1.0 | Amplitude(互換用) |
186
197
 
187
198
  `<name>` はブロック名(`bass`、`melody` など)です。ループごとに独立したアドレスを持つため、複数ループが同じパラメーターを上書きしません。
188
199
 
@@ -1,6 +1,6 @@
1
1
  # PyCodeDJ
2
2
 
3
- [日本語版 README はこちら](https://github.com/kanekoyuichi/pycodedj/blob/main/README.ja.md)
3
+ [日本語版 README はこちら](https://github.com/kanekoyuichi/pycodedj/blob/main/README.ja.md) · [Full Manual (EN)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.md) · [マニュアル (JA)](https://github.com/kanekoyuichi/pycodedj/blob/main/docs/manual.ja.md)
4
4
 
5
5
  A live-coding environment that translates Python code structure into music in real time. Every save changes the performance.
6
6
 
@@ -45,6 +45,7 @@ BPM clock is held by SuperCollider's `TempoClock`. Python only sends parameter u
45
45
  | Control-flow count (if/for/while) | LFO rate (0.1–5.0 Hz) | More branches = faster modulation |
46
46
  | Function definition count | Polyphony voice count (1–4) | Functions = independent voices |
47
47
  | Comment ratio | Reverb depth (0.0–0.8) | More whitespace = more space |
48
+ | `volume=` argument | Amplitude (0.0–1.0) | Direct performer control over loudness |
48
49
 
49
50
  Tempo (BPM) and root pitch are controlled explicitly by the performer, to prevent the foundation of the piece from shifting on every save.
50
51
 
@@ -82,20 +83,22 @@ Open `sc/synths.scd` in the SuperCollider IDE and evaluate it.
82
83
  **2. Write a live-coding file**
83
84
 
84
85
  ```python
85
- # @loop bass interval=2.0
86
- def bass():
86
+ from pycodedj import loop
87
+
88
+ @loop("bass", interval=2.0)
89
+ def bass(volume=0.4):
87
90
  for i in range(8):
88
91
  if i % 2 == 0:
89
92
  pass
90
93
 
91
- # @loop melody interval=0.5
92
- def melody():
94
+ @loop("melody", interval=0.5)
95
+ def melody(volume=0.3):
93
96
  x = 1
94
97
  y = 2
95
98
  return x + y
96
99
 
97
- # @loop pad interval=4.0
98
- def pad():
100
+ @loop("pad", interval=4.0)
101
+ def pad(volume=0.15):
99
102
  # make space
100
103
  # a little more
101
104
  pass
@@ -110,7 +113,7 @@ pycodedj eval demo.py::bass
110
113
  On success, feedback is printed immediately:
111
114
 
112
115
  ```
113
- [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1
116
+ [pycodedj] bass cutoff=418Hz lfo=1.08Hz reverb=0.00 voices=1 amp=0.40
114
117
  ```
115
118
 
116
119
  Other loops keep playing without interruption.
@@ -125,8 +128,6 @@ pycodedj watch demo.py
125
128
 
126
129
  From here, just write code and save.
127
130
 
128
- > **Note on `interval` (current MVP):** Values like `interval=2.0` are parsed and stored, but are not yet sent over OSC. Loop repeat timing is managed by SuperCollider's `TempoClock`. A mechanism to pass interval to SC is planned for a future release.
129
-
130
131
  ---
131
132
 
132
133
  ## Example Files
@@ -134,7 +135,7 @@ From here, just write code and save.
134
135
  | File | Contents |
135
136
  | :--- | :--- |
136
137
  | `examples/demo.py` | Intro demo with bass / melody / pad |
137
- | `examples/club_set.py` | Club-style demo: sub_bass / hat_engine / neon_stab / acid_lead / warehouse_air |
138
+ | `examples/club_set.py` | Layered club groove using kick_hard / bass_rumble / bass_reese and more |
138
139
 
139
140
  ---
140
141
 
@@ -143,8 +144,10 @@ From here, just write code and save.
143
144
  ### Deeper nesting opens the filter
144
145
 
145
146
  ```python
146
- # @loop bass interval=2.0
147
- def bass():
147
+ from pycodedj import loop
148
+
149
+ @loop("bass", interval=2.0)
150
+ def bass(volume=0.4):
148
151
  for i in range(4): # control flow +1
149
152
  for j in range(4): # depth +1, control flow +1
150
153
  if i == j: # depth +1, control flow +1
@@ -154,21 +157,27 @@ def bass():
154
157
  ### More functions = more polyphony
155
158
 
156
159
  ```python
157
- # @loop chord interval=1.0
158
- def voice_a(): pass
159
- def voice_b(): pass
160
- def voice_c(): pass
161
- def voice_d(): pass
160
+ from pycodedj import loop
161
+
162
+ @loop("chord", interval=1.0)
163
+ def chord(volume=0.2):
164
+ def voice_a(): pass
165
+ def voice_b(): pass
166
+ def voice_c(): pass
167
+ def voice_d(): pass
162
168
  ```
163
169
 
164
170
  ### More comments = more space (reverb)
165
171
 
166
172
  ```python
167
- # @loop pad interval=4.0
168
- # leave space here
169
- # a little more
170
- # silence is music
171
- def pad(): pass
173
+ from pycodedj import loop
174
+
175
+ @loop("pad", interval=4.0)
176
+ def pad(volume=0.15):
177
+ # leave space here
178
+ # a little more
179
+ # silence is music
180
+ pass
172
181
  ```
173
182
 
174
183
  ---
@@ -179,10 +188,12 @@ Addresses used to communicate with SuperCollider.
179
188
 
180
189
  | Address | Type | Range | Parameter |
181
190
  | :--- | :--- | :--- | :--- |
182
- | `/pycodedj/loop/<name>/cutoff` | float | 200–4000 Hz | Filter Cutoff |
183
- | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO rate |
184
- | `/pycodedj/loop/<name>/reverb` | float | 0.0–0.8 | Reverb depth |
185
- | `/pycodedj/loop/<name>/voice_count` | int | 14 | Polyphony voice count |
191
+ | `/pycodedj/loop/<name>/params` | int, float, float, float, float | see parameter order | `voice_count`, `cutoff`, `lfo_rate`, `reverb`, `amp` |
192
+ | `/pycodedj/loop/<name>/cutoff` | float | 2004000 Hz | Filter Cutoff (compatibility) |
193
+ | `/pycodedj/loop/<name>/lfo_rate` | float | 0.15.0 Hz | LFO rate (compatibility) |
194
+ | `/pycodedj/loop/<name>/reverb` | float | 0.00.8 | Reverb depth (compatibility) |
195
+ | `/pycodedj/loop/<name>/voice_count` | int | 1–4 | Polyphony voice count (compatibility) |
196
+ | `/pycodedj/loop/<name>/amp` | float | 0.0–1.0 | Amplitude (compatibility) |
186
197
 
187
198
  `<name>` is the loop name (e.g. `bass`, `melody`). Each loop has its own address namespace, so multiple loops never overwrite each other's parameters.
188
199