pycodedj 0.2.1__tar.gz → 0.3.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.
- {pycodedj-0.2.1 → pycodedj-0.3.0}/CHANGELOG.md +24 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/PKG-INFO +34 -6
- {pycodedj-0.2.1 → pycodedj-0.3.0}/README.ja.md +33 -5
- {pycodedj-0.2.1 → pycodedj-0.3.0}/README.md +33 -5
- {pycodedj-0.2.1 → pycodedj-0.3.0}/docs/manual.html +60 -2
- {pycodedj-0.2.1 → pycodedj-0.3.0}/docs/manual.ja.md +86 -2
- {pycodedj-0.2.1 → pycodedj-0.3.0}/docs/manual.md +86 -2
- {pycodedj-0.2.1 → pycodedj-0.3.0}/pyproject.toml +1 -1
- {pycodedj-0.2.1 → pycodedj-0.3.0}/sc/synths.scd +15 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/__init__.py +1 -1
- pycodedj-0.3.0/src/pycodedj/__main__.py +256 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/block_parser.py +11 -4
- pycodedj-0.3.0/src/pycodedj/engine.py +103 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/osc_bridge.py +5 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/watcher.py +8 -4
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/test_block_parser.py +33 -13
- pycodedj-0.3.0/tests/test_engine.py +239 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/test_osc_bridge.py +27 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/test_watcher.py +17 -0
- pycodedj-0.2.1/src/pycodedj/__main__.py +0 -131
- pycodedj-0.2.1/src/pycodedj/engine.py +0 -43
- pycodedj-0.2.1/tests/test_engine.py +0 -50
- {pycodedj-0.2.1 → pycodedj-0.3.0}/.github/workflows/workflow.yml +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/.gitignore +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/LICENSE +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/docs/CNAME +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/docs/index.html +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/examples/club_set.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/examples/demo.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/examples/hello_sc.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/examples/sound_showcase.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/_loop.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/analyzer.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/src/pycodedj/mapper.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/__init__.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/test_analyzer.py +0 -0
- {pycodedj-0.2.1 → pycodedj-0.3.0}/tests/test_mapper.py +0 -0
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-05-08
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- `pycodedj panic` — 全アクティブループを即時停止。SuperCollider 側でシンセを解放し `~loops` / `~loopParams` を初期化する
|
|
8
|
+
- `pycodedj mute <name>` — ループを消音(停止しない)。再評価時もミュート状態を維持
|
|
9
|
+
- `pycodedj unmute <name>` — ミュート解除、音量を復元
|
|
10
|
+
- `pycodedj solo <name>` — 対象ループ以外を全ミュート(CLI は OSC 直送、完全な状態管理は watch セッション内の `Engine.solo()` 推奨)
|
|
11
|
+
- `pycodedj unsolo` — ソロ解除、solo 前のミュート状態に戻す
|
|
12
|
+
- `pycodedj status` — アクティブループの名前・ミュート状態・音量・カットオフを表示
|
|
13
|
+
|
|
14
|
+
### Improvements
|
|
15
|
+
|
|
16
|
+
- `ParseResult` dataclass 導入 — `parse_blocks()` が SyntaxError 時に `ParseResult(ok=False, error=...)` を返すようになり、watch モードでコード編集中に構文エラーがあっても演奏中のループが止まらなくなった
|
|
17
|
+
- `Engine` 内部状態を `LoopState` dataclass で管理 — `muted` / `muted_before_solo` フラグを保持し、mute/solo/unsolo の状態を正確に追跡
|
|
18
|
+
- `eval_block` が OSC 送信成功後に内部状態を更新するよう修正(送信失敗時の状態不整合を解消)
|
|
19
|
+
- `Engine.solo()` に未知のループ名ガードを追加(存在しない名前を渡しても全ループがミュートされない)
|
|
20
|
+
- CLI `unmute` が SuperCollider に永続化された `amp=0` を上書きしてから voice_count を送るよう修正
|
|
21
|
+
|
|
22
|
+
### Docs
|
|
23
|
+
|
|
24
|
+
- README.md / README.ja.md — panic / mute / unmute / status のクイックリファレンスを追加、ロードマップの Sprint 1 を完了に更新
|
|
25
|
+
- `docs/manual.md` / `docs/manual.ja.md` / `docs/manual.html` — セクション 12 に新コマンド 6 つの全リファレンスを追加
|
|
26
|
+
|
|
3
27
|
## [0.2.1] - 2026-05-08
|
|
4
28
|
|
|
5
29
|
### Docs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycodedj
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
License: MIT License with Commons Clause
|
|
5
5
|
|
|
6
6
|
"Commons Clause" License Condition v1.0
|
|
@@ -191,6 +191,33 @@ pycodedj watch demo.py
|
|
|
191
191
|
|
|
192
192
|
From here, just write code and save.
|
|
193
193
|
|
|
194
|
+
**5. Emergency stop**
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pycodedj panic
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Sends a stop signal to all active loops immediately. Use this if something goes wrong during a performance.
|
|
201
|
+
|
|
202
|
+
**6. Mute / solo**
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
pycodedj mute bass # silence a loop without stopping it
|
|
206
|
+
pycodedj unmute bass # restore its sound
|
|
207
|
+
pycodedj solo pad # mute all loops except pad
|
|
208
|
+
pycodedj unsolo # release solo, restore previous mute state
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Note: `mute`, `unmute`, `solo`, and `unsolo` send OSC directly to SuperCollider. For full state management, call `Engine.mute()` / `Engine.solo()` from within a watch session.
|
|
212
|
+
|
|
213
|
+
**7. Loop status**
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
pycodedj status
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Prints the name, mute state, amplitude, and filter cutoff of each active loop.
|
|
220
|
+
|
|
194
221
|
---
|
|
195
222
|
|
|
196
223
|
## Example Files
|
|
@@ -275,11 +302,12 @@ External visualisers such as Hydra can receive the same parameters on a separate
|
|
|
275
302
|
|
|
276
303
|
## Roadmap
|
|
277
304
|
|
|
278
|
-
- [x]
|
|
279
|
-
- [
|
|
280
|
-
- [x]
|
|
281
|
-
- [
|
|
282
|
-
- [ ]
|
|
305
|
+
- [x] Python → SuperCollider OSC prototype
|
|
306
|
+
- [x] Hot-reload live loop implementation (`pycodedj watch`)
|
|
307
|
+
- [x] Sprint 1: Live stability (`panic`, SyntaxError recovery, `mute`/`solo`, `status`)
|
|
308
|
+
- [ ] Sprint 2: Music DSL (`pattern()`, `sample()`, `@loop` parameter expansion, mapping modes)
|
|
309
|
+
- [ ] Sprint 3: Sound design and playability (SynthDef cleanup, `bpm`, `list-synths`)
|
|
310
|
+
- [ ] Sprint 4: README and manual refresh, Hydra visualiser integration
|
|
283
311
|
|
|
284
312
|
---
|
|
285
313
|
|
|
@@ -129,6 +129,33 @@ pycodedj watch demo.py
|
|
|
129
129
|
|
|
130
130
|
あとはエディタでコードを書いて保存するだけです。
|
|
131
131
|
|
|
132
|
+
**5. 緊急停止**
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pycodedj panic
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
全アクティブループに停止信号を即時送信します。演奏中に問題が起きたときに使います。
|
|
139
|
+
|
|
140
|
+
**6. ミュート / ソロ**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pycodedj mute bass # ループを消音(停止はしない)
|
|
144
|
+
pycodedj unmute bass # 音量を元に戻す
|
|
145
|
+
pycodedj solo pad # pad 以外を全ミュート
|
|
146
|
+
pycodedj unsolo # ソロ解除、ミュート状態を元に戻す
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
注意: `mute` / `unmute` / `solo` / `unsolo` は OSC を直接 SuperCollider に送信します。完全な状態管理が必要な場合は watch セッション内で `Engine.mute()` / `Engine.solo()` を呼び出してください。
|
|
150
|
+
|
|
151
|
+
**7. ループのステータス確認**
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pycodedj status
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
アクティブなループの名前・ミュート状態・音量・フィルターカットオフを表示します。
|
|
158
|
+
|
|
132
159
|
---
|
|
133
160
|
|
|
134
161
|
## サンプルファイル
|
|
@@ -213,11 +240,12 @@ Hydra 等の外部ビジュアライザーへは同じパラメーターを別
|
|
|
213
240
|
|
|
214
241
|
## ロードマップ
|
|
215
242
|
|
|
216
|
-
- [x]
|
|
217
|
-
- [
|
|
218
|
-
- [x]
|
|
219
|
-
- [
|
|
220
|
-
- [ ]
|
|
243
|
+
- [x] Python → SuperCollider OSC プロトタイプ
|
|
244
|
+
- [x] ホットリロード・ライブループ実装(`pycodedj watch`)
|
|
245
|
+
- [x] Sprint 1: ライブ安定性(`panic`, SyntaxError維持, `mute`/`solo`, `status`)
|
|
246
|
+
- [ ] Sprint 2: 音楽DSL(`pattern()`, `sample()`, `@loop` パラメータ拡張, mapping モード)
|
|
247
|
+
- [ ] Sprint 3: 音色・演奏性(SynthDef整理, `bpm`, `list-synths`)
|
|
248
|
+
- [ ] Sprint 4: README・マニュアル刷新、Hydra ビジュアライザー統合
|
|
221
249
|
|
|
222
250
|
---
|
|
223
251
|
|
|
@@ -129,6 +129,33 @@ pycodedj watch demo.py
|
|
|
129
129
|
|
|
130
130
|
From here, just write code and save.
|
|
131
131
|
|
|
132
|
+
**5. Emergency stop**
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
pycodedj panic
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Sends a stop signal to all active loops immediately. Use this if something goes wrong during a performance.
|
|
139
|
+
|
|
140
|
+
**6. Mute / solo**
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
pycodedj mute bass # silence a loop without stopping it
|
|
144
|
+
pycodedj unmute bass # restore its sound
|
|
145
|
+
pycodedj solo pad # mute all loops except pad
|
|
146
|
+
pycodedj unsolo # release solo, restore previous mute state
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Note: `mute`, `unmute`, `solo`, and `unsolo` send OSC directly to SuperCollider. For full state management, call `Engine.mute()` / `Engine.solo()` from within a watch session.
|
|
150
|
+
|
|
151
|
+
**7. Loop status**
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pycodedj status
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Prints the name, mute state, amplitude, and filter cutoff of each active loop.
|
|
158
|
+
|
|
132
159
|
---
|
|
133
160
|
|
|
134
161
|
## Example Files
|
|
@@ -213,11 +240,12 @@ External visualisers such as Hydra can receive the same parameters on a separate
|
|
|
213
240
|
|
|
214
241
|
## Roadmap
|
|
215
242
|
|
|
216
|
-
- [x]
|
|
217
|
-
- [
|
|
218
|
-
- [x]
|
|
219
|
-
- [
|
|
220
|
-
- [ ]
|
|
243
|
+
- [x] Python → SuperCollider OSC prototype
|
|
244
|
+
- [x] Hot-reload live loop implementation (`pycodedj watch`)
|
|
245
|
+
- [x] Sprint 1: Live stability (`panic`, SyntaxError recovery, `mute`/`solo`, `status`)
|
|
246
|
+
- [ ] Sprint 2: Music DSL (`pattern()`, `sample()`, `@loop` parameter expansion, mapping modes)
|
|
247
|
+
- [ ] Sprint 3: Sound design and playability (SynthDef cleanup, `bpm`, `list-synths`)
|
|
248
|
+
- [ ] Sprint 4: README and manual refresh, Hydra visualiser integration
|
|
221
249
|
|
|
222
250
|
---
|
|
223
251
|
|
|
@@ -428,7 +428,7 @@ def my_sound(volume=0.4):
|
|
|
428
428
|
|
|
429
429
|
<p>次のように表示されれば成功です。</p>
|
|
430
430
|
|
|
431
|
-
<pre data-lang="text"><code>usage: pycodedj [-h] {eval,watch} ...</code></pre>
|
|
431
|
+
<pre data-lang="text"><code>usage: pycodedj [-h] {eval,watch,panic,mute,unmute,solo,unsolo,status} ...</code></pre>
|
|
432
432
|
|
|
433
433
|
<h3>SuperCollider をインストールする</h3>
|
|
434
434
|
<p>SuperCollider の公式サイト(supercollider.github.io)からインストーラーをダウンロードします。</p>
|
|
@@ -1312,6 +1312,64 @@ pycodedj eval demo.py::pad --sc-port 57200</code></pre>
|
|
|
1312
1312
|
pycodedj watch club_set.py --debounce 0.5
|
|
1313
1313
|
pycodedj watch myfile.py --sc-host 192.168.1.10</code></pre>
|
|
1314
1314
|
|
|
1315
|
+
<h3><code>pycodedj panic</code></h3>
|
|
1316
|
+
<p>全アクティブループに即時停止信号を送ります。演奏中に問題が起きたとき、すべての音をすぐ止めたい場合に使います。SuperCollider 側で実行中のシンセをすべて解放し、ループ状態を初期化します。</p>
|
|
1317
|
+
|
|
1318
|
+
<pre data-lang="text"><code>pycodedj panic [--sc-host HOST] [--sc-port PORT]</code></pre>
|
|
1319
|
+
|
|
1320
|
+
<p><strong>使用例:</strong></p>
|
|
1321
|
+
<pre data-lang="bash"><code id="code-s12-3">pycodedj panic</code></pre>
|
|
1322
|
+
|
|
1323
|
+
<h3><code>pycodedj mute</code></h3>
|
|
1324
|
+
<p>ループを消音します(停止はしません)。ループは引き続き管理され、<code>unmute</code> で音量が復元します。</p>
|
|
1325
|
+
|
|
1326
|
+
<pre data-lang="text"><code>pycodedj mute NAME [--sc-host HOST] [--sc-port PORT]</code></pre>
|
|
1327
|
+
|
|
1328
|
+
<table>
|
|
1329
|
+
<thead>
|
|
1330
|
+
<tr><th>引数・オプション</th><th>説明</th><th>デフォルト</th></tr>
|
|
1331
|
+
</thead>
|
|
1332
|
+
<tbody>
|
|
1333
|
+
<tr><td><code>NAME</code></td><td>ループ名</td><td>—</td></tr>
|
|
1334
|
+
<tr><td><code>--sc-host</code></td><td>SuperCollider のホスト</td><td><code>127.0.0.1</code></td></tr>
|
|
1335
|
+
<tr><td><code>--sc-port</code></td><td>SuperCollider の受信ポート番号</td><td><code>57120</code></td></tr>
|
|
1336
|
+
</tbody>
|
|
1337
|
+
</table>
|
|
1338
|
+
|
|
1339
|
+
<p><strong>使用例:</strong></p>
|
|
1340
|
+
<pre data-lang="bash"><code id="code-s12-4">pycodedj mute bass</code></pre>
|
|
1341
|
+
|
|
1342
|
+
<p><strong>注意:</strong> CLI は OSC を直接 SuperCollider に送信します。ループを再評価してもミュート状態を維持したい場合は、watch セッション内で <code>Engine.mute()</code> を呼び出してください。</p>
|
|
1343
|
+
|
|
1344
|
+
<h3><code>pycodedj unmute</code></h3>
|
|
1345
|
+
<p>ミュートしたループの音量を元に戻します。</p>
|
|
1346
|
+
|
|
1347
|
+
<pre data-lang="text"><code>pycodedj unmute NAME [--sc-host HOST] [--sc-port PORT]</code></pre>
|
|
1348
|
+
|
|
1349
|
+
<p><strong>使用例:</strong></p>
|
|
1350
|
+
<pre data-lang="bash"><code id="code-s12-5">pycodedj unmute bass</code></pre>
|
|
1351
|
+
|
|
1352
|
+
<h3><code>pycodedj solo</code></h3>
|
|
1353
|
+
<p><strong>CLI からはサポートされていません。</strong> Solo は watch プロセスの状態へのアクセスが必要です。watch セッション内で <code>Engine.solo()</code> を直接呼び出してください。</p>
|
|
1354
|
+
|
|
1355
|
+
<h3><code>pycodedj unsolo</code></h3>
|
|
1356
|
+
<p><strong>CLI からはサポートされていません。</strong> watch セッション内で <code>Engine.unsolo()</code> を直接呼び出してください。</p>
|
|
1357
|
+
|
|
1358
|
+
<h3><code>pycodedj status</code></h3>
|
|
1359
|
+
<p>アクティブなループの名前・ミュート状態・音量・フィルターカットオフを表示します。</p>
|
|
1360
|
+
|
|
1361
|
+
<pre data-lang="text"><code>pycodedj status [--sc-host HOST] [--sc-port PORT]</code></pre>
|
|
1362
|
+
|
|
1363
|
+
<p>出力形式:</p>
|
|
1364
|
+
<pre data-lang="text"><code>Loop State Amp Cutoff
|
|
1365
|
+
bass playing 0.40 1340Hz
|
|
1366
|
+
pad muted 0.15 200Hz</code></pre>
|
|
1367
|
+
|
|
1368
|
+
<p><strong>注意:</strong> <code>status</code> は <code>pycodedj watch</code> とは別プロセスで動作するため、watch プロセスの状態を読み取れません。CLI から単独で実行すると「no active loops」と表示されます。</p>
|
|
1369
|
+
|
|
1370
|
+
<p><strong>使用例:</strong></p>
|
|
1371
|
+
<pre data-lang="bash"><code id="code-s12-6">pycodedj status</code></pre>
|
|
1372
|
+
|
|
1315
1373
|
<h3>ループの書き方</h3>
|
|
1316
1374
|
|
|
1317
1375
|
<pre data-lang="python"><code id="code-s12-3">from pycodedj import loop
|
|
@@ -1465,7 +1523,7 @@ bridge = OscBridge(audio=OscEndpoint("127.0.0.1", 57120))
|
|
|
1465
1523
|
engine = Engine(bridge=bridge)
|
|
1466
1524
|
|
|
1467
1525
|
source = open("demo.py").read()
|
|
1468
|
-
blocks = {b.name: b for b in parse_blocks(source)}
|
|
1526
|
+
blocks = {b.name: b for b in parse_blocks(source).blocks}
|
|
1469
1527
|
|
|
1470
1528
|
params = engine.eval_block(blocks["bass"])
|
|
1471
1529
|
if params is not None:
|
|
@@ -117,7 +117,7 @@ pycodedj --help
|
|
|
117
117
|
次のように表示されれば成功です。
|
|
118
118
|
|
|
119
119
|
```
|
|
120
|
-
usage: pycodedj [-h] {eval,watch} ...
|
|
120
|
+
usage: pycodedj [-h] {eval,watch,panic,mute,unmute,solo,unsolo,status} ...
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
### SuperCollider をインストールする
|
|
@@ -987,6 +987,90 @@ pycodedj watch club_set.py --debounce 0.5
|
|
|
987
987
|
pycodedj watch myfile.py --sc-host 192.168.1.10
|
|
988
988
|
```
|
|
989
989
|
|
|
990
|
+
### `pycodedj panic`
|
|
991
|
+
|
|
992
|
+
全アクティブループに即時停止信号を送ります。
|
|
993
|
+
|
|
994
|
+
```
|
|
995
|
+
pycodedj panic [--sc-host HOST] [--sc-port PORT]
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
演奏中に問題が起きたとき、すべての音をすぐ止めたい場合に使います。SuperCollider 側で実行中のシンセをすべて解放し、ループ状態を初期化します。
|
|
999
|
+
|
|
1000
|
+
**使用例:**
|
|
1001
|
+
|
|
1002
|
+
```bash
|
|
1003
|
+
pycodedj panic
|
|
1004
|
+
```
|
|
1005
|
+
|
|
1006
|
+
### `pycodedj mute`
|
|
1007
|
+
|
|
1008
|
+
ループを消音します(停止はしません)。ループは引き続き管理され、unmute で音量が復元します。
|
|
1009
|
+
|
|
1010
|
+
```
|
|
1011
|
+
pycodedj mute NAME [--sc-host HOST] [--sc-port PORT]
|
|
1012
|
+
```
|
|
1013
|
+
|
|
1014
|
+
| 引数・オプション | 説明 | デフォルト |
|
|
1015
|
+
| :--- | :--- | :--- |
|
|
1016
|
+
| `NAME` | ループ名 | — |
|
|
1017
|
+
| `--sc-host` | SuperCollider のホスト | `127.0.0.1` |
|
|
1018
|
+
| `--sc-port` | SuperCollider の受信ポート番号 | `57120` |
|
|
1019
|
+
|
|
1020
|
+
**使用例:**
|
|
1021
|
+
|
|
1022
|
+
```bash
|
|
1023
|
+
pycodedj mute bass
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
> **注意:** CLI は OSC を直接 SuperCollider に送信します。ループを再評価してもミュート状態を維持したい場合は、watch セッション内で `Engine.mute()` を呼び出してください。
|
|
1027
|
+
|
|
1028
|
+
### `pycodedj unmute`
|
|
1029
|
+
|
|
1030
|
+
ミュートしたループの音量を元に戻します。
|
|
1031
|
+
|
|
1032
|
+
```
|
|
1033
|
+
pycodedj unmute NAME [--sc-host HOST] [--sc-port PORT]
|
|
1034
|
+
```
|
|
1035
|
+
|
|
1036
|
+
**使用例:**
|
|
1037
|
+
|
|
1038
|
+
```bash
|
|
1039
|
+
pycodedj unmute bass
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
### `pycodedj solo`
|
|
1043
|
+
|
|
1044
|
+
> **CLI からはサポートされていません。** Solo は watch プロセスの状態へのアクセスが必要です。watch セッション内で `Engine.solo()` を直接呼び出してください。
|
|
1045
|
+
|
|
1046
|
+
### `pycodedj unsolo`
|
|
1047
|
+
|
|
1048
|
+
> **CLI からはサポートされていません。** watch セッション内で `Engine.unsolo()` を直接呼び出してください。
|
|
1049
|
+
|
|
1050
|
+
### `pycodedj status`
|
|
1051
|
+
|
|
1052
|
+
アクティブなループの名前・ミュート状態・音量・フィルターカットオフを表示します。
|
|
1053
|
+
|
|
1054
|
+
```
|
|
1055
|
+
pycodedj status [--sc-host HOST] [--sc-port PORT]
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
出力形式:
|
|
1059
|
+
|
|
1060
|
+
```
|
|
1061
|
+
Loop State Amp Cutoff
|
|
1062
|
+
bass playing 0.40 1340Hz
|
|
1063
|
+
pad muted 0.15 200Hz
|
|
1064
|
+
```
|
|
1065
|
+
|
|
1066
|
+
> **注意:** `status` は `pycodedj watch` とは別プロセスで動作するため、watch プロセスの状態を読み取ることができません。CLI から単独で実行すると「no active loops」と表示されます。
|
|
1067
|
+
|
|
1068
|
+
**使用例:**
|
|
1069
|
+
|
|
1070
|
+
```bash
|
|
1071
|
+
pycodedj status
|
|
1072
|
+
```
|
|
1073
|
+
|
|
990
1074
|
### ループの書き方
|
|
991
1075
|
|
|
992
1076
|
```python
|
|
@@ -1048,7 +1132,7 @@ bridge = OscBridge(audio=OscEndpoint("127.0.0.1", 57120))
|
|
|
1048
1132
|
engine = Engine(bridge=bridge)
|
|
1049
1133
|
|
|
1050
1134
|
source = open("demo.py").read()
|
|
1051
|
-
blocks = {b.name: b for b in parse_blocks(source)}
|
|
1135
|
+
blocks = {b.name: b for b in parse_blocks(source).blocks}
|
|
1052
1136
|
|
|
1053
1137
|
params = engine.eval_block(blocks["bass"])
|
|
1054
1138
|
if params is not None:
|
|
@@ -117,7 +117,7 @@ pycodedj --help
|
|
|
117
117
|
If you see this, you're good:
|
|
118
118
|
|
|
119
119
|
```
|
|
120
|
-
usage: pycodedj [-h] {eval,watch} ...
|
|
120
|
+
usage: pycodedj [-h] {eval,watch,panic,mute,unmute,solo,unsolo,status} ...
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
### Installing SuperCollider
|
|
@@ -985,6 +985,90 @@ pycodedj watch club_set.py --debounce 0.5
|
|
|
985
985
|
pycodedj watch myfile.py --sc-host 192.168.1.10
|
|
986
986
|
```
|
|
987
987
|
|
|
988
|
+
### `pycodedj panic`
|
|
989
|
+
|
|
990
|
+
Sends an immediate stop signal to all active loops.
|
|
991
|
+
|
|
992
|
+
```
|
|
993
|
+
pycodedj panic [--sc-host HOST] [--sc-port PORT]
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
Use this when something goes wrong during a performance and you need everything to stop now. SuperCollider frees all running synths and clears its loop state.
|
|
997
|
+
|
|
998
|
+
**Example:**
|
|
999
|
+
|
|
1000
|
+
```bash
|
|
1001
|
+
pycodedj panic
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
### `pycodedj mute`
|
|
1005
|
+
|
|
1006
|
+
Silences a loop without stopping it. The loop continues to be tracked; unmuting restores its sound.
|
|
1007
|
+
|
|
1008
|
+
```
|
|
1009
|
+
pycodedj mute NAME [--sc-host HOST] [--sc-port PORT]
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
| Argument / option | Description | Default |
|
|
1013
|
+
| :--- | :--- | :--- |
|
|
1014
|
+
| `NAME` | Loop name | — |
|
|
1015
|
+
| `--sc-host` | SuperCollider host | `127.0.0.1` |
|
|
1016
|
+
| `--sc-port` | SuperCollider receive port | `57120` |
|
|
1017
|
+
|
|
1018
|
+
**Example:**
|
|
1019
|
+
|
|
1020
|
+
```bash
|
|
1021
|
+
pycodedj mute bass
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
> **Note:** The CLI sends OSC directly to SuperCollider. For full state tracking (so that re-evaluating a loop while muted keeps it silent), call `Engine.mute()` within a watch session instead.
|
|
1025
|
+
|
|
1026
|
+
### `pycodedj unmute`
|
|
1027
|
+
|
|
1028
|
+
Restores sound for a muted loop.
|
|
1029
|
+
|
|
1030
|
+
```
|
|
1031
|
+
pycodedj unmute NAME [--sc-host HOST] [--sc-port PORT]
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
**Example:**
|
|
1035
|
+
|
|
1036
|
+
```bash
|
|
1037
|
+
pycodedj unmute bass
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
### `pycodedj solo`
|
|
1041
|
+
|
|
1042
|
+
> **Not supported from the CLI.** Solo requires access to the watch process state. Call `Engine.solo()` directly within a watch session.
|
|
1043
|
+
|
|
1044
|
+
### `pycodedj unsolo`
|
|
1045
|
+
|
|
1046
|
+
> **Not supported from the CLI.** Call `Engine.unsolo()` directly within a watch session.
|
|
1047
|
+
|
|
1048
|
+
### `pycodedj status`
|
|
1049
|
+
|
|
1050
|
+
Prints the name, mute state, amplitude, and filter cutoff for each active loop.
|
|
1051
|
+
|
|
1052
|
+
```
|
|
1053
|
+
pycodedj status [--sc-host HOST] [--sc-port PORT]
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
Output format:
|
|
1057
|
+
|
|
1058
|
+
```
|
|
1059
|
+
Loop State Amp Cutoff
|
|
1060
|
+
bass playing 0.40 1340Hz
|
|
1061
|
+
pad muted 0.15 200Hz
|
|
1062
|
+
```
|
|
1063
|
+
|
|
1064
|
+
> **Note:** `status` runs in a separate process from `pycodedj watch` and cannot read the watch process state. It will show "no active loops" when invoked from the CLI.
|
|
1065
|
+
|
|
1066
|
+
**Example:**
|
|
1067
|
+
|
|
1068
|
+
```bash
|
|
1069
|
+
pycodedj status
|
|
1070
|
+
```
|
|
1071
|
+
|
|
988
1072
|
### Loop syntax
|
|
989
1073
|
|
|
990
1074
|
```python
|
|
@@ -1046,7 +1130,7 @@ bridge = OscBridge(audio=OscEndpoint("127.0.0.1", 57120))
|
|
|
1046
1130
|
engine = Engine(bridge=bridge)
|
|
1047
1131
|
|
|
1048
1132
|
source = open("demo.py").read()
|
|
1049
|
-
blocks = {b.name: b for b in parse_blocks(source)}
|
|
1133
|
+
blocks = {b.name: b for b in parse_blocks(source).blocks}
|
|
1050
1134
|
|
|
1051
1135
|
params = engine.eval_block(blocks["bass"])
|
|
1052
1136
|
if params is not None:
|
|
@@ -669,6 +669,21 @@ s.waitForBoot({
|
|
|
669
669
|
// OSCFunc with nil path receives every incoming OSC message and we filter by prefix.
|
|
670
670
|
// var は SC では実行文より前に宣言しなければならないため、
|
|
671
671
|
// すべての var をクロージャ先頭にまとめる。
|
|
672
|
+
// ── Panic handler ────────────────────────────────────────────────────────
|
|
673
|
+
// /pycodedj/panic: すべての Synth を即停止し ~loops / ~loopParams を初期化する。
|
|
674
|
+
// OSCFunc は再登録時に上書きされるため、スクリプト再実行時でも安全。
|
|
675
|
+
if (~pycodedjPanic.notNil) { ~pycodedjPanic.free };
|
|
676
|
+
~pycodedjPanic = OSCFunc({ |msg, time, addr|
|
|
677
|
+
~loops.keysValuesDo({ |name, synths|
|
|
678
|
+
if (synths.notNil) {
|
|
679
|
+
synths.do({ |synth| synth.set(\gate, 0) });
|
|
680
|
+
};
|
|
681
|
+
});
|
|
682
|
+
~loops = Dictionary.new;
|
|
683
|
+
~loopParams = Dictionary.new;
|
|
684
|
+
"PyCodeDJ panic: all loops stopped.".postln;
|
|
685
|
+
}, '/pycodedj/panic');
|
|
686
|
+
|
|
672
687
|
if (~pycodedjOSC.notNil) {
|
|
673
688
|
thisProcess.removeOSCRecvFunc(~pycodedjOSC);
|
|
674
689
|
};
|