audio-as-code 0.1.0__py3-none-any.whl
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.
- audio_as_code/__init__.py +44 -0
- audio_as_code/__main__.py +3 -0
- audio_as_code/_audio.py +87 -0
- audio_as_code/_export_rules.py +32 -0
- audio_as_code/_orchestra_profiles.py +188 -0
- audio_as_code/_paths.py +36 -0
- audio_as_code/_voices.py +173 -0
- audio_as_code/acoustics.py +126 -0
- audio_as_code/automation.py +40 -0
- audio_as_code/cli.py +171 -0
- audio_as_code/demo.py +106 -0
- audio_as_code/effects.py +85 -0
- audio_as_code/extended.py +283 -0
- audio_as_code/inspection.py +351 -0
- audio_as_code/instruments.py +923 -0
- audio_as_code/midi.py +192 -0
- audio_as_code/model.py +292 -0
- audio_as_code/orchestra.py +481 -0
- audio_as_code/pattern.py +151 -0
- audio_as_code/physical.py +189 -0
- audio_as_code/py.typed +0 -0
- audio_as_code/render.py +230 -0
- audio_as_code-0.1.0.dist-info/METADATA +340 -0
- audio_as_code-0.1.0.dist-info/RECORD +27 -0
- audio_as_code-0.1.0.dist-info/WHEEL +4 -0
- audio_as_code-0.1.0.dist-info/entry_points.txt +2 -0
- audio_as_code-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
"""Instrument families and the code-generated synthesis engines behind them.
|
|
2
|
+
|
|
3
|
+
Planned entries describe the framework's scope; only available entries may appear
|
|
4
|
+
in scores. The metadata also supplies tone capabilities and MIDI mappings.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import asdict, dataclass
|
|
10
|
+
from types import MappingProxyType
|
|
11
|
+
from typing import Literal
|
|
12
|
+
|
|
13
|
+
Instrument = Literal[
|
|
14
|
+
"sine",
|
|
15
|
+
"triangle",
|
|
16
|
+
"pluck",
|
|
17
|
+
"bass",
|
|
18
|
+
"pad",
|
|
19
|
+
"kick",
|
|
20
|
+
"snare",
|
|
21
|
+
"hat",
|
|
22
|
+
"guitar",
|
|
23
|
+
"marimba",
|
|
24
|
+
"bell",
|
|
25
|
+
"electric_guitar",
|
|
26
|
+
"bass_guitar",
|
|
27
|
+
"harp",
|
|
28
|
+
"ukulele",
|
|
29
|
+
"banjo",
|
|
30
|
+
"violin",
|
|
31
|
+
"viola",
|
|
32
|
+
"cello",
|
|
33
|
+
"double_bass",
|
|
34
|
+
"piano",
|
|
35
|
+
"electric_piano",
|
|
36
|
+
"organ",
|
|
37
|
+
"harpsichord",
|
|
38
|
+
"flute",
|
|
39
|
+
"clarinet",
|
|
40
|
+
"saxophone",
|
|
41
|
+
"oboe",
|
|
42
|
+
"bassoon",
|
|
43
|
+
"trumpet",
|
|
44
|
+
"trombone",
|
|
45
|
+
"french_horn",
|
|
46
|
+
"tuba",
|
|
47
|
+
"toms",
|
|
48
|
+
"cymbal",
|
|
49
|
+
"congas",
|
|
50
|
+
"bongos",
|
|
51
|
+
"tambourine",
|
|
52
|
+
"xylophone",
|
|
53
|
+
"vibraphone",
|
|
54
|
+
"glockenspiel",
|
|
55
|
+
"timpani",
|
|
56
|
+
"synthesizer",
|
|
57
|
+
"drum_machine",
|
|
58
|
+
"theremin",
|
|
59
|
+
"mandolin",
|
|
60
|
+
"kalimba",
|
|
61
|
+
"celesta",
|
|
62
|
+
"recorder",
|
|
63
|
+
]
|
|
64
|
+
Status = Literal["available", "planned"]
|
|
65
|
+
FamilyId = Literal[
|
|
66
|
+
"plucked_strings",
|
|
67
|
+
"bowed_strings",
|
|
68
|
+
"keyboards",
|
|
69
|
+
"woodwinds",
|
|
70
|
+
"brass",
|
|
71
|
+
"percussion",
|
|
72
|
+
"pitched_percussion",
|
|
73
|
+
"electronic",
|
|
74
|
+
]
|
|
75
|
+
EngineId = Literal["string", "air_column", "modal", "membrane", "electronic"]
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True)
|
|
79
|
+
class Family:
|
|
80
|
+
id: FamilyId
|
|
81
|
+
name: str
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass(frozen=True)
|
|
85
|
+
class Engine:
|
|
86
|
+
id: EngineId
|
|
87
|
+
name: str
|
|
88
|
+
status: Status
|
|
89
|
+
description: str
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True)
|
|
93
|
+
class InstrumentInfo:
|
|
94
|
+
id: str
|
|
95
|
+
name: str
|
|
96
|
+
family: FamilyId
|
|
97
|
+
engine: EngineId
|
|
98
|
+
status: Status
|
|
99
|
+
description: str
|
|
100
|
+
tone_controls: tuple[str, ...] = ()
|
|
101
|
+
default_decay_seconds: float | None = None
|
|
102
|
+
midi_program: int | None = None
|
|
103
|
+
midi_note: int | None = None
|
|
104
|
+
preview_pitch: int = 60
|
|
105
|
+
default_tone: tuple[tuple[str, float], ...] = ()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
FAMILIES = (
|
|
109
|
+
Family("plucked_strings", "Plucked strings"),
|
|
110
|
+
Family("bowed_strings", "Bowed strings"),
|
|
111
|
+
Family("keyboards", "Keyboards"),
|
|
112
|
+
Family("woodwinds", "Woodwinds"),
|
|
113
|
+
Family("brass", "Brass"),
|
|
114
|
+
Family("percussion", "Drums and percussion"),
|
|
115
|
+
Family("pitched_percussion", "Pitched percussion"),
|
|
116
|
+
Family("electronic", "Electronic"),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
ENGINES = (
|
|
120
|
+
Engine(
|
|
121
|
+
"string",
|
|
122
|
+
"Vibrating strings",
|
|
123
|
+
"available",
|
|
124
|
+
"Damped guitar delay loop, modal plucked/struck strings, and spectral "
|
|
125
|
+
"bowed-tone prototypes.",
|
|
126
|
+
),
|
|
127
|
+
Engine(
|
|
128
|
+
"air_column",
|
|
129
|
+
"Air columns",
|
|
130
|
+
"available",
|
|
131
|
+
"Harmonic source/filter approximations of pipes, reeds, and brass; no "
|
|
132
|
+
"nonlinear bore solver yet.",
|
|
133
|
+
),
|
|
134
|
+
Engine(
|
|
135
|
+
"modal",
|
|
136
|
+
"Bars, bells, and plates",
|
|
137
|
+
"available",
|
|
138
|
+
"Damped modes for bars, bells, tines, and plate-inspired metal resonances.",
|
|
139
|
+
),
|
|
140
|
+
Engine(
|
|
141
|
+
"membrane",
|
|
142
|
+
"Membranes",
|
|
143
|
+
"available",
|
|
144
|
+
"Modal drumhead approximations with strike noise and tension relaxation; no "
|
|
145
|
+
"coupled cavity solver.",
|
|
146
|
+
),
|
|
147
|
+
Engine(
|
|
148
|
+
"electronic",
|
|
149
|
+
"Electronic synthesis",
|
|
150
|
+
"available",
|
|
151
|
+
"Oscillators, harmonic sums, noise, envelopes, and generated percussion.",
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
_DECAY_CONTROLS = ("brightness", "decay_seconds")
|
|
156
|
+
|
|
157
|
+
INSTRUMENTS = (
|
|
158
|
+
InstrumentInfo(
|
|
159
|
+
"guitar",
|
|
160
|
+
"Acoustic guitar",
|
|
161
|
+
"plucked_strings",
|
|
162
|
+
"string",
|
|
163
|
+
"available",
|
|
164
|
+
"Tuned plucked-string loop with generated contact noise and a driven body "
|
|
165
|
+
"resonance approximation; no coupled body solver.",
|
|
166
|
+
(*_DECAY_CONTROLS, "pluck_position"),
|
|
167
|
+
3.0,
|
|
168
|
+
midi_program=24,
|
|
169
|
+
),
|
|
170
|
+
InstrumentInfo(
|
|
171
|
+
"electric_guitar",
|
|
172
|
+
"Electric guitar",
|
|
173
|
+
"plucked_strings",
|
|
174
|
+
"string",
|
|
175
|
+
"available",
|
|
176
|
+
"Modal steel-string pluck with pickup-position response; clean tone, no "
|
|
177
|
+
"amplifier circuit model.",
|
|
178
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
179
|
+
default_decay_seconds=4.5,
|
|
180
|
+
midi_program=27,
|
|
181
|
+
midi_note=None,
|
|
182
|
+
preview_pitch=52,
|
|
183
|
+
default_tone=(("pluck_position", 0.16),),
|
|
184
|
+
),
|
|
185
|
+
InstrumentInfo(
|
|
186
|
+
"bass_guitar",
|
|
187
|
+
"Bass guitar",
|
|
188
|
+
"plucked_strings",
|
|
189
|
+
"string",
|
|
190
|
+
"available",
|
|
191
|
+
"Low modal strings with pickup response and strong upper-mode damping; no "
|
|
192
|
+
"fret-contact model.",
|
|
193
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
194
|
+
default_decay_seconds=4.5,
|
|
195
|
+
midi_program=33,
|
|
196
|
+
midi_note=None,
|
|
197
|
+
preview_pitch=36,
|
|
198
|
+
default_tone=(("pluck_position", 0.24),),
|
|
199
|
+
),
|
|
200
|
+
InstrumentInfo(
|
|
201
|
+
"harp",
|
|
202
|
+
"Harp",
|
|
203
|
+
"plucked_strings",
|
|
204
|
+
"string",
|
|
205
|
+
"available",
|
|
206
|
+
"Long-decay modal string with lightly detuned polarizations and driven body "
|
|
207
|
+
"resonances; no sympathetic-string coupling.",
|
|
208
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
209
|
+
default_decay_seconds=6,
|
|
210
|
+
midi_program=46,
|
|
211
|
+
midi_note=None,
|
|
212
|
+
preview_pitch=60,
|
|
213
|
+
default_tone=(("pluck_position", 0.32),),
|
|
214
|
+
),
|
|
215
|
+
InstrumentInfo(
|
|
216
|
+
"ukulele",
|
|
217
|
+
"Ukulele",
|
|
218
|
+
"plucked_strings",
|
|
219
|
+
"string",
|
|
220
|
+
"available",
|
|
221
|
+
"Short modal pluck with fast upper-mode decay and driven small-body resonances.",
|
|
222
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
223
|
+
default_decay_seconds=1.8,
|
|
224
|
+
midi_program=24,
|
|
225
|
+
midi_note=None,
|
|
226
|
+
preview_pitch=67,
|
|
227
|
+
default_tone=(("pluck_position", 0.25),),
|
|
228
|
+
),
|
|
229
|
+
InstrumentInfo(
|
|
230
|
+
"banjo",
|
|
231
|
+
"Banjo",
|
|
232
|
+
"plucked_strings",
|
|
233
|
+
"string",
|
|
234
|
+
"available",
|
|
235
|
+
"Bright modal pluck driving a designed drumhead-like response; no "
|
|
236
|
+
"coupled head/string solver.",
|
|
237
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
238
|
+
default_decay_seconds=1.6,
|
|
239
|
+
midi_program=105,
|
|
240
|
+
midi_note=None,
|
|
241
|
+
preview_pitch=60,
|
|
242
|
+
default_tone=(("pluck_position", 0.12),),
|
|
243
|
+
),
|
|
244
|
+
InstrumentInfo(
|
|
245
|
+
"violin",
|
|
246
|
+
"Violin",
|
|
247
|
+
"bowed_strings",
|
|
248
|
+
"string",
|
|
249
|
+
"available",
|
|
250
|
+
"Bowed-tone harmonic source/filter approximation with body formants, onset, "
|
|
251
|
+
"evolving bow noise, and delayed vibrato; no friction solver.",
|
|
252
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz"),
|
|
253
|
+
default_decay_seconds=None,
|
|
254
|
+
midi_program=40,
|
|
255
|
+
midi_note=None,
|
|
256
|
+
preview_pitch=69,
|
|
257
|
+
default_tone=(("vibrato_depth_cents", 14), ("vibrato_rate_hz", 5.5)),
|
|
258
|
+
),
|
|
259
|
+
InstrumentInfo(
|
|
260
|
+
"viola",
|
|
261
|
+
"Viola",
|
|
262
|
+
"bowed_strings",
|
|
263
|
+
"string",
|
|
264
|
+
"available",
|
|
265
|
+
"Bowed-tone spectral approximation with lower body formants, a slower "
|
|
266
|
+
"onset, bow noise, and vibrato.",
|
|
267
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz"),
|
|
268
|
+
default_decay_seconds=None,
|
|
269
|
+
midi_program=41,
|
|
270
|
+
midi_note=None,
|
|
271
|
+
preview_pitch=60,
|
|
272
|
+
default_tone=(("vibrato_depth_cents", 12), ("vibrato_rate_hz", 5.1)),
|
|
273
|
+
),
|
|
274
|
+
InstrumentInfo(
|
|
275
|
+
"cello",
|
|
276
|
+
"Cello",
|
|
277
|
+
"bowed_strings",
|
|
278
|
+
"string",
|
|
279
|
+
"available",
|
|
280
|
+
"Bowed-tone spectral approximation with low body formants, gradual onset, "
|
|
281
|
+
"bow noise, and vibrato.",
|
|
282
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz"),
|
|
283
|
+
default_decay_seconds=None,
|
|
284
|
+
midi_program=42,
|
|
285
|
+
midi_note=None,
|
|
286
|
+
preview_pitch=48,
|
|
287
|
+
default_tone=(("vibrato_depth_cents", 13), ("vibrato_rate_hz", 4.7)),
|
|
288
|
+
),
|
|
289
|
+
InstrumentInfo(
|
|
290
|
+
"double_bass",
|
|
291
|
+
"Double bass",
|
|
292
|
+
"bowed_strings",
|
|
293
|
+
"string",
|
|
294
|
+
"available",
|
|
295
|
+
"Low bowed-tone spectral approximation with slow onset and bow noise; "
|
|
296
|
+
"pizzicato is not implemented.",
|
|
297
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz"),
|
|
298
|
+
default_decay_seconds=None,
|
|
299
|
+
midi_program=43,
|
|
300
|
+
midi_note=None,
|
|
301
|
+
preview_pitch=36,
|
|
302
|
+
default_tone=(("vibrato_depth_cents", 8), ("vibrato_rate_hz", 4.2)),
|
|
303
|
+
),
|
|
304
|
+
InstrumentInfo(
|
|
305
|
+
"piano",
|
|
306
|
+
"Piano",
|
|
307
|
+
"keyboards",
|
|
308
|
+
"string",
|
|
309
|
+
"available",
|
|
310
|
+
"Finite hammer-driven stiff strings with shared unison bridge losses and a designed "
|
|
311
|
+
"soundboard response; binary Track.pedal damper gates, without half-pedal or "
|
|
312
|
+
"sympathetic resonance.",
|
|
313
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
314
|
+
default_decay_seconds=5,
|
|
315
|
+
midi_program=0,
|
|
316
|
+
midi_note=None,
|
|
317
|
+
preview_pitch=60,
|
|
318
|
+
default_tone=(),
|
|
319
|
+
),
|
|
320
|
+
InstrumentInfo(
|
|
321
|
+
"electric_piano",
|
|
322
|
+
"Electric piano",
|
|
323
|
+
"keyboards",
|
|
324
|
+
"modal",
|
|
325
|
+
"available",
|
|
326
|
+
"Struck tine-like modes with a short bright attack and gentle amplitude "
|
|
327
|
+
"tremolo; no pickup circuit solver.",
|
|
328
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
329
|
+
default_decay_seconds=4,
|
|
330
|
+
midi_program=4,
|
|
331
|
+
midi_note=None,
|
|
332
|
+
preview_pitch=60,
|
|
333
|
+
default_tone=(),
|
|
334
|
+
),
|
|
335
|
+
InstrumentInfo(
|
|
336
|
+
"organ",
|
|
337
|
+
"Organ",
|
|
338
|
+
"keyboards",
|
|
339
|
+
"air_column",
|
|
340
|
+
"available",
|
|
341
|
+
"Sustained additive pipe-registration approximation with generated onset "
|
|
342
|
+
"chiff; no airflow solver.",
|
|
343
|
+
tone_controls=("brightness", "breath"),
|
|
344
|
+
default_decay_seconds=None,
|
|
345
|
+
midi_program=19,
|
|
346
|
+
midi_note=None,
|
|
347
|
+
preview_pitch=60,
|
|
348
|
+
default_tone=(("breath", 0.15),),
|
|
349
|
+
),
|
|
350
|
+
InstrumentInfo(
|
|
351
|
+
"harpsichord",
|
|
352
|
+
"Harpsichord",
|
|
353
|
+
"keyboards",
|
|
354
|
+
"string",
|
|
355
|
+
"available",
|
|
356
|
+
"Bright near-bridge modal pluck with slight unison beating and driven body resonances.",
|
|
357
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position"),
|
|
358
|
+
default_decay_seconds=3,
|
|
359
|
+
midi_program=6,
|
|
360
|
+
midi_note=None,
|
|
361
|
+
preview_pitch=60,
|
|
362
|
+
default_tone=(("pluck_position", 0.09),),
|
|
363
|
+
),
|
|
364
|
+
InstrumentInfo(
|
|
365
|
+
"flute",
|
|
366
|
+
"Flute",
|
|
367
|
+
"woodwinds",
|
|
368
|
+
"air_column",
|
|
369
|
+
"available",
|
|
370
|
+
"Airy harmonic source/filter approximation with weak upper partials, "
|
|
371
|
+
"evolving breath noise and delayed vibrato; no jet/bore solver.",
|
|
372
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
373
|
+
default_decay_seconds=None,
|
|
374
|
+
midi_program=73,
|
|
375
|
+
midi_note=None,
|
|
376
|
+
preview_pitch=72,
|
|
377
|
+
default_tone=(("breath", 0.45), ("vibrato_depth_cents", 10), ("vibrato_rate_hz", 5)),
|
|
378
|
+
),
|
|
379
|
+
InstrumentInfo(
|
|
380
|
+
"clarinet",
|
|
381
|
+
"Clarinet",
|
|
382
|
+
"woodwinds",
|
|
383
|
+
"air_column",
|
|
384
|
+
"available",
|
|
385
|
+
"Odd-harmonic reed-tone approximation with weak even partials and generated "
|
|
386
|
+
"breath; no reed/bore feedback solver.",
|
|
387
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
388
|
+
default_decay_seconds=None,
|
|
389
|
+
midi_program=71,
|
|
390
|
+
midi_note=None,
|
|
391
|
+
preview_pitch=60,
|
|
392
|
+
default_tone=(("breath", 0.12), ("vibrato_depth_cents", 0), ("vibrato_rate_hz", 5)),
|
|
393
|
+
),
|
|
394
|
+
InstrumentInfo(
|
|
395
|
+
"saxophone",
|
|
396
|
+
"Saxophone",
|
|
397
|
+
"woodwinds",
|
|
398
|
+
"air_column",
|
|
399
|
+
"available",
|
|
400
|
+
"Reed-tone spectral approximation with broad harmonics, formants, generated "
|
|
401
|
+
"breath, and vibrato.",
|
|
402
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
403
|
+
default_decay_seconds=None,
|
|
404
|
+
midi_program=65,
|
|
405
|
+
midi_note=None,
|
|
406
|
+
preview_pitch=57,
|
|
407
|
+
default_tone=(("breath", 0.3), ("vibrato_depth_cents", 12), ("vibrato_rate_hz", 5.2)),
|
|
408
|
+
),
|
|
409
|
+
InstrumentInfo(
|
|
410
|
+
"oboe",
|
|
411
|
+
"Oboe",
|
|
412
|
+
"woodwinds",
|
|
413
|
+
"air_column",
|
|
414
|
+
"available",
|
|
415
|
+
"Double-reed-tone spectral approximation with strong upper harmonics, a "
|
|
416
|
+
"nasal formant, breath, and vibrato.",
|
|
417
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
418
|
+
default_decay_seconds=None,
|
|
419
|
+
midi_program=68,
|
|
420
|
+
midi_note=None,
|
|
421
|
+
preview_pitch=67,
|
|
422
|
+
default_tone=(("breath", 0.16), ("vibrato_depth_cents", 9), ("vibrato_rate_hz", 5.6)),
|
|
423
|
+
),
|
|
424
|
+
InstrumentInfo(
|
|
425
|
+
"bassoon",
|
|
426
|
+
"Bassoon",
|
|
427
|
+
"woodwinds",
|
|
428
|
+
"air_column",
|
|
429
|
+
"available",
|
|
430
|
+
"Low double-reed-tone spectral approximation with designed formants, "
|
|
431
|
+
"breath, and gradual onset.",
|
|
432
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
433
|
+
default_decay_seconds=None,
|
|
434
|
+
midi_program=70,
|
|
435
|
+
midi_note=None,
|
|
436
|
+
preview_pitch=48,
|
|
437
|
+
default_tone=(("breath", 0.16), ("vibrato_depth_cents", 7), ("vibrato_rate_hz", 4.8)),
|
|
438
|
+
),
|
|
439
|
+
InstrumentInfo(
|
|
440
|
+
"trumpet",
|
|
441
|
+
"Trumpet",
|
|
442
|
+
"brass",
|
|
443
|
+
"air_column",
|
|
444
|
+
"available",
|
|
445
|
+
"Brass-tone spectral approximation with a brightening onset and "
|
|
446
|
+
"velocity-sensitive harmonics; no lip/bore feedback solver.",
|
|
447
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
448
|
+
default_decay_seconds=None,
|
|
449
|
+
midi_program=56,
|
|
450
|
+
midi_note=None,
|
|
451
|
+
preview_pitch=67,
|
|
452
|
+
default_tone=(("breath", 0.08), ("vibrato_depth_cents", 5), ("vibrato_rate_hz", 5.3)),
|
|
453
|
+
),
|
|
454
|
+
InstrumentInfo(
|
|
455
|
+
"trombone",
|
|
456
|
+
"Trombone",
|
|
457
|
+
"brass",
|
|
458
|
+
"air_column",
|
|
459
|
+
"available",
|
|
460
|
+
"Brass-tone spectral approximation with broad low harmonics and breath; no "
|
|
461
|
+
"continuous slide geometry.",
|
|
462
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
463
|
+
default_decay_seconds=None,
|
|
464
|
+
midi_program=57,
|
|
465
|
+
midi_note=None,
|
|
466
|
+
preview_pitch=48,
|
|
467
|
+
default_tone=(("breath", 0.1), ("vibrato_depth_cents", 4), ("vibrato_rate_hz", 4.8)),
|
|
468
|
+
),
|
|
469
|
+
InstrumentInfo(
|
|
470
|
+
"french_horn",
|
|
471
|
+
"French horn",
|
|
472
|
+
"brass",
|
|
473
|
+
"air_column",
|
|
474
|
+
"available",
|
|
475
|
+
"Soft brass-tone spectral approximation with rounded harmonics and a gradual onset.",
|
|
476
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
477
|
+
default_decay_seconds=None,
|
|
478
|
+
midi_program=60,
|
|
479
|
+
midi_note=None,
|
|
480
|
+
preview_pitch=53,
|
|
481
|
+
default_tone=(("breath", 0.08), ("vibrato_depth_cents", 3), ("vibrato_rate_hz", 4.8)),
|
|
482
|
+
),
|
|
483
|
+
InstrumentInfo(
|
|
484
|
+
"tuba",
|
|
485
|
+
"Tuba",
|
|
486
|
+
"brass",
|
|
487
|
+
"air_column",
|
|
488
|
+
"available",
|
|
489
|
+
"Low brass-tone spectral approximation with a slow pressure-like onset and "
|
|
490
|
+
"generated breath.",
|
|
491
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "breath"),
|
|
492
|
+
default_decay_seconds=None,
|
|
493
|
+
midi_program=58,
|
|
494
|
+
midi_note=None,
|
|
495
|
+
preview_pitch=36,
|
|
496
|
+
default_tone=(("breath", 0.12), ("vibrato_depth_cents", 3), ("vibrato_rate_hz", 4)),
|
|
497
|
+
),
|
|
498
|
+
InstrumentInfo(
|
|
499
|
+
"kick",
|
|
500
|
+
"Kick",
|
|
501
|
+
"percussion",
|
|
502
|
+
"electronic",
|
|
503
|
+
"available",
|
|
504
|
+
"Synthetic pitch-swept sine drum; not a drumhead physics model.",
|
|
505
|
+
midi_note=36,
|
|
506
|
+
),
|
|
507
|
+
InstrumentInfo(
|
|
508
|
+
"snare",
|
|
509
|
+
"Snare",
|
|
510
|
+
"percussion",
|
|
511
|
+
"electronic",
|
|
512
|
+
"available",
|
|
513
|
+
"Synthetic noise and tonal transient; not a drumhead physics model.",
|
|
514
|
+
midi_note=38,
|
|
515
|
+
),
|
|
516
|
+
InstrumentInfo(
|
|
517
|
+
"hat",
|
|
518
|
+
"Hi-hat",
|
|
519
|
+
"percussion",
|
|
520
|
+
"electronic",
|
|
521
|
+
"available",
|
|
522
|
+
"Synthetic filtered-noise and inharmonic-mode hi-hat; no metal-plate physics solver.",
|
|
523
|
+
midi_note=42,
|
|
524
|
+
),
|
|
525
|
+
InstrumentInfo(
|
|
526
|
+
"toms",
|
|
527
|
+
"Toms",
|
|
528
|
+
"percussion",
|
|
529
|
+
"membrane",
|
|
530
|
+
"available",
|
|
531
|
+
"Fixed-tuning modal drumhead approximation with strike noise and relaxing "
|
|
532
|
+
"tension and designed shell coloration; no shell/cavity feedback coupling.",
|
|
533
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
534
|
+
default_decay_seconds=1.1,
|
|
535
|
+
midi_program=None,
|
|
536
|
+
midi_note=45,
|
|
537
|
+
preview_pitch=45,
|
|
538
|
+
default_tone=(),
|
|
539
|
+
),
|
|
540
|
+
InstrumentInfo(
|
|
541
|
+
"cymbal",
|
|
542
|
+
"Cymbal",
|
|
543
|
+
"percussion",
|
|
544
|
+
"modal",
|
|
545
|
+
"available",
|
|
546
|
+
"Seeded inharmonic metal-mode cloud with frequency-dependent damping; "
|
|
547
|
+
"plate-inspired, not a nonlinear plate solver.",
|
|
548
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
549
|
+
default_decay_seconds=4,
|
|
550
|
+
midi_program=None,
|
|
551
|
+
midi_note=49,
|
|
552
|
+
preview_pitch=49,
|
|
553
|
+
default_tone=(),
|
|
554
|
+
),
|
|
555
|
+
InstrumentInfo(
|
|
556
|
+
"congas",
|
|
557
|
+
"Congas",
|
|
558
|
+
"percussion",
|
|
559
|
+
"membrane",
|
|
560
|
+
"available",
|
|
561
|
+
"Open-hand drum approximation using designed membrane modes and a generated "
|
|
562
|
+
"slap transient; one articulation.",
|
|
563
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
564
|
+
default_decay_seconds=0.9,
|
|
565
|
+
midi_program=None,
|
|
566
|
+
midi_note=64,
|
|
567
|
+
preview_pitch=64,
|
|
568
|
+
default_tone=(),
|
|
569
|
+
),
|
|
570
|
+
InstrumentInfo(
|
|
571
|
+
"bongos",
|
|
572
|
+
"Bongos",
|
|
573
|
+
"percussion",
|
|
574
|
+
"membrane",
|
|
575
|
+
"available",
|
|
576
|
+
"High fixed-tuning membrane modes with a short generated hand-strike "
|
|
577
|
+
"transient; one articulation.",
|
|
578
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
579
|
+
default_decay_seconds=0.55,
|
|
580
|
+
midi_program=None,
|
|
581
|
+
midi_note=60,
|
|
582
|
+
preview_pitch=60,
|
|
583
|
+
default_tone=(),
|
|
584
|
+
),
|
|
585
|
+
InstrumentInfo(
|
|
586
|
+
"tambourine",
|
|
587
|
+
"Tambourine",
|
|
588
|
+
"percussion",
|
|
589
|
+
"modal",
|
|
590
|
+
"available",
|
|
591
|
+
"Generated jingle collisions exciting inharmonic metal modes; no recorded "
|
|
592
|
+
"hits or membrane component.",
|
|
593
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
594
|
+
default_decay_seconds=0.65,
|
|
595
|
+
midi_program=None,
|
|
596
|
+
midi_note=54,
|
|
597
|
+
preview_pitch=54,
|
|
598
|
+
default_tone=(),
|
|
599
|
+
),
|
|
600
|
+
InstrumentInfo(
|
|
601
|
+
"marimba",
|
|
602
|
+
"Marimba",
|
|
603
|
+
"pitched_percussion",
|
|
604
|
+
"modal",
|
|
605
|
+
"available",
|
|
606
|
+
"Simplified tuned wooden-bar modes with independent decay.",
|
|
607
|
+
_DECAY_CONTROLS,
|
|
608
|
+
1.4,
|
|
609
|
+
midi_program=12,
|
|
610
|
+
),
|
|
611
|
+
InstrumentInfo(
|
|
612
|
+
"xylophone",
|
|
613
|
+
"Xylophone",
|
|
614
|
+
"pitched_percussion",
|
|
615
|
+
"modal",
|
|
616
|
+
"available",
|
|
617
|
+
"Bright tuned wooden-bar modal approximation with rapid overtone decay and "
|
|
618
|
+
"a hard generated strike.",
|
|
619
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
620
|
+
default_decay_seconds=0.8,
|
|
621
|
+
midi_program=13,
|
|
622
|
+
midi_note=None,
|
|
623
|
+
preview_pitch=72,
|
|
624
|
+
default_tone=(),
|
|
625
|
+
),
|
|
626
|
+
InstrumentInfo(
|
|
627
|
+
"vibraphone",
|
|
628
|
+
"Vibraphone",
|
|
629
|
+
"pitched_percussion",
|
|
630
|
+
"modal",
|
|
631
|
+
"available",
|
|
632
|
+
"Tuned metal-bar modal approximation with long decay and 5.5 Hz amplitude tremolo.",
|
|
633
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
634
|
+
default_decay_seconds=5.5,
|
|
635
|
+
midi_program=11,
|
|
636
|
+
midi_note=None,
|
|
637
|
+
preview_pitch=60,
|
|
638
|
+
default_tone=(),
|
|
639
|
+
),
|
|
640
|
+
InstrumentInfo(
|
|
641
|
+
"glockenspiel",
|
|
642
|
+
"Glockenspiel",
|
|
643
|
+
"pitched_percussion",
|
|
644
|
+
"modal",
|
|
645
|
+
"available",
|
|
646
|
+
"High inharmonic metal-bar modes with a short generated strike and long ringing decay.",
|
|
647
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
648
|
+
default_decay_seconds=5,
|
|
649
|
+
midi_program=9,
|
|
650
|
+
midi_note=None,
|
|
651
|
+
preview_pitch=84,
|
|
652
|
+
default_tone=(),
|
|
653
|
+
),
|
|
654
|
+
InstrumentInfo(
|
|
655
|
+
"bell",
|
|
656
|
+
"Bell",
|
|
657
|
+
"pitched_percussion",
|
|
658
|
+
"modal",
|
|
659
|
+
"available",
|
|
660
|
+
"Designed inharmonic chime modes; not fitted to a particular bell.",
|
|
661
|
+
_DECAY_CONTROLS,
|
|
662
|
+
5.0,
|
|
663
|
+
midi_program=14,
|
|
664
|
+
),
|
|
665
|
+
InstrumentInfo(
|
|
666
|
+
"timpani",
|
|
667
|
+
"Timpani",
|
|
668
|
+
"pitched_percussion",
|
|
669
|
+
"membrane",
|
|
670
|
+
"available",
|
|
671
|
+
"Pitchable quasi-harmonic membrane modes with tension relaxation and a soft "
|
|
672
|
+
"strike; no kettle-cavity solver.",
|
|
673
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
674
|
+
default_decay_seconds=2.8,
|
|
675
|
+
midi_program=47,
|
|
676
|
+
midi_note=None,
|
|
677
|
+
preview_pitch=43,
|
|
678
|
+
default_tone=(),
|
|
679
|
+
),
|
|
680
|
+
InstrumentInfo(
|
|
681
|
+
"sine",
|
|
682
|
+
"Sine oscillator",
|
|
683
|
+
"electronic",
|
|
684
|
+
"electronic",
|
|
685
|
+
"available",
|
|
686
|
+
"A single sinusoidal oscillator.",
|
|
687
|
+
midi_program=80,
|
|
688
|
+
),
|
|
689
|
+
InstrumentInfo(
|
|
690
|
+
"triangle",
|
|
691
|
+
"Triangle oscillator",
|
|
692
|
+
"electronic",
|
|
693
|
+
"electronic",
|
|
694
|
+
"available",
|
|
695
|
+
"A finite odd-harmonic approximation of a triangle wave.",
|
|
696
|
+
midi_program=80,
|
|
697
|
+
),
|
|
698
|
+
InstrumentInfo(
|
|
699
|
+
"pluck",
|
|
700
|
+
"Synth pluck",
|
|
701
|
+
"electronic",
|
|
702
|
+
"electronic",
|
|
703
|
+
"available",
|
|
704
|
+
"Decaying harmonic synthesis; distinct from the physical guitar voice.",
|
|
705
|
+
midi_program=10,
|
|
706
|
+
),
|
|
707
|
+
InstrumentInfo(
|
|
708
|
+
"bass",
|
|
709
|
+
"Synth bass",
|
|
710
|
+
"electronic",
|
|
711
|
+
"electronic",
|
|
712
|
+
"available",
|
|
713
|
+
"A three-harmonic bass synthesizer; distinct from a bass-guitar model.",
|
|
714
|
+
midi_program=38,
|
|
715
|
+
),
|
|
716
|
+
InstrumentInfo(
|
|
717
|
+
"pad",
|
|
718
|
+
"Synth pad",
|
|
719
|
+
"electronic",
|
|
720
|
+
"electronic",
|
|
721
|
+
"available",
|
|
722
|
+
"A sustained harmonic voice with a soft attack and release.",
|
|
723
|
+
midi_program=89,
|
|
724
|
+
),
|
|
725
|
+
InstrumentInfo(
|
|
726
|
+
"synthesizer",
|
|
727
|
+
"Multi-oscillator synthesizer",
|
|
728
|
+
"electronic",
|
|
729
|
+
"electronic",
|
|
730
|
+
"available",
|
|
731
|
+
"Three band-limited detuned harmonic oscillators with a brightness-decay "
|
|
732
|
+
"filter envelope; fixed topology.",
|
|
733
|
+
tone_controls=("brightness", "detune_cents"),
|
|
734
|
+
default_decay_seconds=None,
|
|
735
|
+
midi_program=81,
|
|
736
|
+
midi_note=None,
|
|
737
|
+
preview_pitch=60,
|
|
738
|
+
default_tone=(("detune_cents", 8),),
|
|
739
|
+
),
|
|
740
|
+
InstrumentInfo(
|
|
741
|
+
"drum_machine",
|
|
742
|
+
"Drum machine",
|
|
743
|
+
"electronic",
|
|
744
|
+
"electronic",
|
|
745
|
+
"available",
|
|
746
|
+
"Generated percussion kit: note pitch chooses kick, snare, hat, tom, "
|
|
747
|
+
"cymbal, tambourine, bongo, or conga.",
|
|
748
|
+
tone_controls=(),
|
|
749
|
+
default_decay_seconds=None,
|
|
750
|
+
midi_program=None,
|
|
751
|
+
midi_note=36,
|
|
752
|
+
preview_pitch=36,
|
|
753
|
+
default_tone=(),
|
|
754
|
+
),
|
|
755
|
+
InstrumentInfo(
|
|
756
|
+
"theremin",
|
|
757
|
+
"Theremin",
|
|
758
|
+
"electronic",
|
|
759
|
+
"electronic",
|
|
760
|
+
"available",
|
|
761
|
+
"Sustained electronic tone with vibrato and an optional exponential pitch "
|
|
762
|
+
"glide into each note.",
|
|
763
|
+
tone_controls=("brightness", "vibrato_depth_cents", "vibrato_rate_hz", "glide_semitones"),
|
|
764
|
+
default_decay_seconds=None,
|
|
765
|
+
midi_program=80,
|
|
766
|
+
midi_note=None,
|
|
767
|
+
preview_pitch=72,
|
|
768
|
+
default_tone=(
|
|
769
|
+
("vibrato_depth_cents", 22),
|
|
770
|
+
("vibrato_rate_hz", 5.7),
|
|
771
|
+
("glide_semitones", 0),
|
|
772
|
+
),
|
|
773
|
+
),
|
|
774
|
+
)
|
|
775
|
+
|
|
776
|
+
# Append new voices so existing discovery entries retain their relative order.
|
|
777
|
+
INSTRUMENTS += (
|
|
778
|
+
InstrumentInfo(
|
|
779
|
+
"mandolin",
|
|
780
|
+
"Mandolin",
|
|
781
|
+
"plucked_strings",
|
|
782
|
+
"string",
|
|
783
|
+
"available",
|
|
784
|
+
"Paired stiff-string normal modes with a shared bridge stiffness and projected "
|
|
785
|
+
"radiation losses, plus a generated body response; no full string/body solver. "
|
|
786
|
+
"Detune is the total uncoupled-string separation in cents.",
|
|
787
|
+
tone_controls=("brightness", "decay_seconds", "pluck_position", "detune_cents"),
|
|
788
|
+
default_decay_seconds=1.8,
|
|
789
|
+
midi_program=25,
|
|
790
|
+
preview_pitch=67,
|
|
791
|
+
default_tone=(("pluck_position", 0.18), ("detune_cents", 4)),
|
|
792
|
+
),
|
|
793
|
+
InstrumentInfo(
|
|
794
|
+
"kalimba",
|
|
795
|
+
"Kalimba",
|
|
796
|
+
"pitched_percussion",
|
|
797
|
+
"modal",
|
|
798
|
+
"available",
|
|
799
|
+
"Fixed-free lamella modes driven by a finite thumb-contact force, with a generated "
|
|
800
|
+
"wooden-box response; idealized uniform tine, no buzz attachments or tine coupling.",
|
|
801
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
802
|
+
default_decay_seconds=2.0,
|
|
803
|
+
midi_program=108,
|
|
804
|
+
preview_pitch=72,
|
|
805
|
+
),
|
|
806
|
+
InstrumentInfo(
|
|
807
|
+
"celesta",
|
|
808
|
+
"Celesta",
|
|
809
|
+
"keyboards",
|
|
810
|
+
"modal",
|
|
811
|
+
"available",
|
|
812
|
+
"Free-free metal-bar modes driven by a finite felt-hammer force and a pitch-matched "
|
|
813
|
+
"generated resonator; idealized uniform bar, no keyboard mechanics or pedal model.",
|
|
814
|
+
tone_controls=("brightness", "decay_seconds"),
|
|
815
|
+
default_decay_seconds=3.4,
|
|
816
|
+
midi_program=8,
|
|
817
|
+
preview_pitch=84,
|
|
818
|
+
),
|
|
819
|
+
InstrumentInfo(
|
|
820
|
+
"recorder",
|
|
821
|
+
"Recorder",
|
|
822
|
+
"woodwinds",
|
|
823
|
+
"air_column",
|
|
824
|
+
"available",
|
|
825
|
+
"Soprano-like recorder prototype: band-limited asymmetric jet-source harmonics, "
|
|
826
|
+
"designed bore/radiation filtering, breath and onset; no nonlinear jet/bore coupling "
|
|
827
|
+
"or fingering-dependent impedance model.",
|
|
828
|
+
tone_controls=("brightness", "breath", "vibrato_depth_cents", "vibrato_rate_hz"),
|
|
829
|
+
midi_program=74,
|
|
830
|
+
preview_pitch=79,
|
|
831
|
+
default_tone=(("breath", 0.08), ("vibrato_depth_cents", 0), ("vibrato_rate_hz", 5)),
|
|
832
|
+
),
|
|
833
|
+
)
|
|
834
|
+
|
|
835
|
+
_BY_ID = MappingProxyType({instrument.id: instrument for instrument in INSTRUMENTS})
|
|
836
|
+
_FAMILY_IDS = frozenset(family.id for family in FAMILIES)
|
|
837
|
+
_ENGINE_IDS = frozenset(engine.id for engine in ENGINES)
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
def get_instrument(instrument_id: str) -> InstrumentInfo:
|
|
841
|
+
"""Inspect an instrument, including planned entries. Does not imply playability."""
|
|
842
|
+
try:
|
|
843
|
+
return _BY_ID[instrument_id]
|
|
844
|
+
except KeyError:
|
|
845
|
+
raise ValueError(f"unknown instrument {instrument_id!r}; use 'aac instruments'") from None
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
def require_instrument(instrument_id: str) -> InstrumentInfo:
|
|
849
|
+
"""Resolve a playable instrument; never silently substitute another sound."""
|
|
850
|
+
instrument = get_instrument(instrument_id)
|
|
851
|
+
if instrument.status != "available":
|
|
852
|
+
raise ValueError(
|
|
853
|
+
f"instrument {instrument_id!r} is planned and cannot be rendered yet; "
|
|
854
|
+
"use 'aac instruments' for available voices"
|
|
855
|
+
)
|
|
856
|
+
return instrument
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
def list_instruments(
|
|
860
|
+
*,
|
|
861
|
+
family: str | None = None,
|
|
862
|
+
engine: str | None = None,
|
|
863
|
+
include_planned: bool = False,
|
|
864
|
+
) -> tuple[InstrumentInfo, ...]:
|
|
865
|
+
"""Discover playable voices by default; opt in to see the full framework scope."""
|
|
866
|
+
if family is not None and family not in _FAMILY_IDS:
|
|
867
|
+
raise ValueError(f"unknown instrument family {family!r}")
|
|
868
|
+
if engine is not None and engine not in _ENGINE_IDS:
|
|
869
|
+
raise ValueError(f"unknown synthesis engine {engine!r}")
|
|
870
|
+
return tuple(
|
|
871
|
+
instrument
|
|
872
|
+
for instrument in INSTRUMENTS
|
|
873
|
+
if (include_planned or instrument.status == "available")
|
|
874
|
+
and (family is None or instrument.family == family)
|
|
875
|
+
and (engine is None or instrument.engine == engine)
|
|
876
|
+
)
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
def instrument_catalog(
|
|
880
|
+
*,
|
|
881
|
+
family: str | None = None,
|
|
882
|
+
engine: str | None = None,
|
|
883
|
+
include_planned: bool = False,
|
|
884
|
+
) -> dict:
|
|
885
|
+
"""Machine-readable discovery; engine availability denotes an initial implementation."""
|
|
886
|
+
selected = list_instruments(family=family, engine=engine, include_planned=include_planned)
|
|
887
|
+
return {
|
|
888
|
+
"catalog_version": "1",
|
|
889
|
+
"synthesis_policy": "code_only",
|
|
890
|
+
"families": [asdict(item) for item in FAMILIES],
|
|
891
|
+
"engines": [asdict(item) for item in ENGINES],
|
|
892
|
+
"instruments": [asdict(item) for item in selected],
|
|
893
|
+
"counts": {
|
|
894
|
+
"available": sum(item.status == "available" for item in selected),
|
|
895
|
+
"planned": sum(item.status == "planned" for item in selected),
|
|
896
|
+
},
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
PHYSICAL_INSTRUMENTS = frozenset(
|
|
901
|
+
item.id for item in INSTRUMENTS if item.status == "available" and item.engine != "electronic"
|
|
902
|
+
)
|
|
903
|
+
DRUM_NOTES = MappingProxyType(
|
|
904
|
+
{item.id: item.midi_note for item in INSTRUMENTS if item.midi_note is not None}
|
|
905
|
+
)
|
|
906
|
+
PROGRAMS = MappingProxyType(
|
|
907
|
+
{item.id: item.midi_program for item in INSTRUMENTS if item.midi_program is not None}
|
|
908
|
+
)
|
|
909
|
+
|
|
910
|
+
# The drum-machine track selects generated voices by GM percussion pitch.
|
|
911
|
+
# Other percussion IDs keep their historical fixed-pitch export behavior.
|
|
912
|
+
KIT_NOTES = MappingProxyType(
|
|
913
|
+
{
|
|
914
|
+
36: "kick",
|
|
915
|
+
38: "snare",
|
|
916
|
+
42: "hat",
|
|
917
|
+
45: "toms",
|
|
918
|
+
49: "cymbal",
|
|
919
|
+
54: "tambourine",
|
|
920
|
+
60: "bongos",
|
|
921
|
+
64: "congas",
|
|
922
|
+
}
|
|
923
|
+
)
|