vinsynlib 0.3.0__tar.gz → 0.4.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.
- {vinsynlib-0.3.0/src/vinsynlib.egg-info → vinsynlib-0.4.0}/PKG-INFO +174 -146
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/README.md +174 -146
- vinsynlib-0.4.0/docs/unify2.md +534 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/pyproject.toml +5 -1
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/__init__.py +1 -1
- vinsynlib-0.4.0/src/vinsynlib/backup.py +182 -0
- vinsynlib-0.4.0/src/vinsynlib/catalog.py +381 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/config.py +440 -1
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/devchecks.py +23 -13
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/favorites.py +15 -0
- vinsynlib-0.4.0/src/vinsynlib/livenames.py +142 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/midi.py +288 -1
- vinsynlib-0.4.0/src/vinsynlib/render.py +79 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/ui/__init__.py +3 -2
- vinsynlib-0.4.0/src/vinsynlib/ui/browser.py +65 -0
- vinsynlib-0.4.0/src/vinsynlib/ui/confirm.py +108 -0
- vinsynlib-0.4.0/src/vinsynlib/ui/modals.py +669 -0
- vinsynlib-0.4.0/src/vinsynlib/ui/prompt.py +74 -0
- vinsynlib-0.4.0/src/vinsynlib/ui/protocol.py +25 -0
- vinsynlib-0.4.0/src/vinsynlib/ui/work.py +149 -0
- vinsynlib-0.4.0/src/vinsynlib/undo.py +116 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0/src/vinsynlib.egg-info}/PKG-INFO +174 -146
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib.egg-info/SOURCES.txt +26 -1
- vinsynlib-0.4.0/tests/test_app_contract.py +53 -0
- vinsynlib-0.4.0/tests/test_backup.py +100 -0
- vinsynlib-0.4.0/tests/test_catalog.py +292 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_config.py +322 -0
- vinsynlib-0.4.0/tests/test_confirm_screen.py +80 -0
- vinsynlib-0.4.0/tests/test_identity.py +199 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_midi_and_checks.py +122 -0
- vinsynlib-0.4.0/tests/test_modals.py +517 -0
- vinsynlib-0.4.0/tests/test_prompt_screen.py +65 -0
- vinsynlib-0.4.0/tests/test_rating_cell.py +37 -0
- vinsynlib-0.4.0/tests/test_readme_modules.py +29 -0
- vinsynlib-0.4.0/tests/test_render.py +57 -0
- vinsynlib-0.4.0/tests/test_transport.py +144 -0
- vinsynlib-0.4.0/tests/test_undo.py +209 -0
- vinsynlib-0.4.0/tests/test_work.py +215 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/COPYING +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/DISCLAIMER.md +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/LICENSE +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/MANIFEST.in +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/Makefile +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/docs/UX-SPEC.md +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/setup.cfg +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/cli.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/conformance.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/keys.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/py.typed +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/spec.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/terms.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib/ui/hints.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib.egg-info/dependency_links.txt +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib.egg-info/requires.txt +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/src/vinsynlib.egg-info/top_level.txt +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_favorites.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_hints.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_ux.py +0 -0
- {vinsynlib-0.3.0 → vinsynlib-0.4.0}/tests/test_version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vinsynlib
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Shared base for ROMpler instrument browsers: settings, favourites, banks, dumps, CLI and key conventions
|
|
5
5
|
License-Expression: GPL-2.0-or-later
|
|
6
6
|
Project-URL: Homepage, https://github.com/lentferj/vinsynlib
|
|
@@ -34,15 +34,17 @@ SPDX-FileCopyrightText: Copyright (C) 2026 vinsynLib contributors
|
|
|
34
34
|
The shared base of a family of terminal instrument browsers.
|
|
35
35
|
|
|
36
36
|
Nine sibling programs browse nine instruments over MIDI from a terminal:
|
|
37
|
-
|
|
38
|
-
[
|
|
39
|
-
|
|
40
|
-
[kwsed](https://github.com/lentferj/kwsed) (Korg Wavestation SR),
|
|
41
|
-
[nanosyned](https://github.com/lentferj/nanosyned) (Alesis NanoSynth),
|
|
42
|
-
[p2ked](https://github.com/lentferj/p2ked) (E-mu Proteus 2000),
|
|
37
|
+
emorphed (E-mu Morpheus), ensqsqed (Ensoniq SQ-R Plus),
|
|
38
|
+
[eosed](https://github.com/lentferj/eosed) (E-mu E4XT), kwsed (Korg
|
|
39
|
+
Wavestation SR), nanosyned (Alesis NanoSynth), p2ked (E-mu Proteus 2000),
|
|
43
40
|
[rxved](https://github.com/lentferj/rxved) (Roland XV-2020),
|
|
44
|
-
[s3ked](https://github.com/lentferj/s3ked) (Akai S1000/S3000) and
|
|
45
|
-
|
|
41
|
+
[s3ked](https://github.com/lentferj/s3ked) (Akai S1000/S3000) and x5ded
|
|
42
|
+
(Korg X5D/X5DR). Several of these repositories are not public yet, which is
|
|
43
|
+
why only some of the names above are links.
|
|
44
|
+
|
|
45
|
+
A tenth project, [k2kremote](https://github.com/lentferj/k2kremote), is a
|
|
46
|
+
remote for the Kurzweil K2000 rather than a browser, and depends on the same
|
|
47
|
+
shared code.
|
|
46
48
|
|
|
47
49
|
They grew separately, which is the right way to learn what an instrument
|
|
48
50
|
does and the wrong way to arrive at nine copies of the same code. This
|
|
@@ -51,93 +53,6 @@ a change to one of them happens once instead of nine times.
|
|
|
51
53
|
|
|
52
54
|
---
|
|
53
55
|
|
|
54
|
-
## Support this project
|
|
55
|
-
|
|
56
|
-
is free software and always will be. Nothing is behind a paywall, no
|
|
57
|
-
feature is withheld, and none of what follows changes that.
|
|
58
|
-
|
|
59
|
-
But if it has been useful — if it saved you an evening of mapping zones
|
|
60
|
-
by hand, or got a library onto a machine that had no way of reading it, or
|
|
61
|
-
**best of all, if it has your vintage instrument switched on and in use more often
|
|
62
|
-
than it was, and you are having more fun with it** — then please consider
|
|
63
|
-
supporting the work.
|
|
64
|
-
|
|
65
|
-
**Because here is what it has actually cost:**
|
|
66
|
-
|
|
67
|
-
- **Real machines on a real bench.** Much of what these tools know about these
|
|
68
|
-
formats was measured on hardware rather than read anywhere, because for most
|
|
69
|
-
of it there is nowhere to read it. That needs the machines — the instruments
|
|
70
|
-
themselves — and it puts hours of wear on hardware that has been locked up and
|
|
71
|
-
recovered more than once in the course of it. Some of these instruments were
|
|
72
|
-
bought specifically to add and verify a format; the others were already here,
|
|
73
|
-
because the person doing this is a vintage instrument enthusiast first and the
|
|
74
|
-
projects exist because the instruments were in the room.
|
|
75
|
-
- **Dozens — realistically hundreds — of hours of human time.** Format
|
|
76
|
-
reverse-engineering is slow: measure, be wrong, measure again. A single
|
|
77
|
-
parameter law in this README can represent an evening at the bench.
|
|
78
|
-
- **AI assistance, which is a paid service**, used heavily throughout and not
|
|
79
|
-
cheap at this volume.
|
|
80
|
-
|
|
81
|
-
**This is support, not a donation — and the distinction is a legal one, not a
|
|
82
|
-
turn of phrase.** The maintainer is based in Germany, where payments like these
|
|
83
|
-
are *not* `Spenden` in the tax sense: they count as **taxable income** for the
|
|
84
|
-
recipient and are **not tax-deductible** for the giver. So this section is
|
|
85
|
-
titled *Support*, deliberately, and no receipt for tax purposes can be issued.
|
|
86
|
-
(That is a statement of how it is handled here, not tax advice.)
|
|
87
|
-
|
|
88
|
-
If the project saved you the work, you can support it through
|
|
89
|
-
**[GitHub Sponsors](https://github.com/sponsors/lentferj)** — the *Sponsor*
|
|
90
|
-
button at the top of the repository. Payment is handled entirely by GitHub and
|
|
91
|
-
Stripe, so bank and tax details are never handed to the person paying.
|
|
92
|
-
|
|
93
|
-
**Support is not expected, and it is not the only currency.**
|
|
94
|
-
|
|
95
|
-
- **Bug reports** — ideally with the bank, preset or disk image that produced
|
|
96
|
-
them. A tool's failures are usually specific to one file rather than
|
|
97
|
-
general, and without that file they are very hard to reproduce.
|
|
98
|
-
- **Confirmations from hardware that is not on this bench**, which matters more
|
|
99
|
-
here than for a single-machine tool. These tools write for whole *families*
|
|
100
|
-
of instruments, and the bench holds only a subset. Whether a variant accepts
|
|
101
|
-
what we write is genuinely unknown, and several notes say "on this unit" for
|
|
102
|
-
that reason. A "loads fine here too", or a "no, mine refuses it", is worth a
|
|
103
|
-
great deal.
|
|
104
|
-
- **Corrections to the reverse-engineering notes.** The wrong turns are
|
|
105
|
-
recorded next to the findings in `docs/RESOLUTION_NOTES.md` — retractions
|
|
106
|
-
included, because a finding that was withdrawn is as useful as one that
|
|
107
|
-
stood. If any of it is wrong in a way that is still costing someone time,
|
|
108
|
-
saying so improves the record.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## AI assistance & human authorship
|
|
113
|
-
|
|
114
|
-
was built by its human author together with AI assistance. The
|
|
115
|
-
**ideas, the project vision, and every feature** came from the human author;
|
|
116
|
-
AI assisted with **writing the code and analyzing the binary formats**.
|
|
117
|
-
Crucially, the **reverse engineering rests on hands-on human work** — all testing
|
|
118
|
-
and verification on real hardware, creating the reference images/banks on those
|
|
119
|
-
instruments (disk saves, SysEx probes), and aural A/B comparison of presets —
|
|
120
|
-
which is what makes the results correct.
|
|
121
|
-
Full account in [DISCLAIMER.md](DISCLAIMER.md).
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## ⚠️ Use at your own risk — back up first
|
|
128
|
-
|
|
129
|
-
is provided **as is, with absolutely no warranty and no liability**
|
|
130
|
-
for data loss or **hardware damage**. You assume all risk. Full terms:
|
|
131
|
-
[DISCLAIMER.md](DISCLAIMER.md).
|
|
132
|
-
|
|
133
|
-
Before you use this software, **make good, current backups of all your files** —
|
|
134
|
-
and of any existing banks on your instrument and storage media. These tools can
|
|
135
|
-
write to hardware and storage media; a mistake, a bug, or untested output could
|
|
136
|
-
overwrite or corrupt data, or be rejected by hardware. Always test on a spare
|
|
137
|
-
unit or emulator **before** connecting irreplaceable equipment.
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
56
|
## What is in here, and what is not
|
|
142
57
|
|
|
143
58
|
**In here:** how a preference is remembered, where a favourite lives, what
|
|
@@ -153,7 +68,7 @@ selects which bank is that instrument's business and stays put.
|
|
|
153
68
|
|
|
154
69
|
```
|
|
155
70
|
vinsynlib/
|
|
156
|
-
config.py the settings cache: port, channel, device ID
|
|
71
|
+
config.py the settings cache: port, channel, device ID, UI state
|
|
157
72
|
favorites.py the favourites database: SQLite, slots, ratings, tags
|
|
158
73
|
keys.py the keymap and the legend
|
|
159
74
|
cli.py the command line every tool builds the same way
|
|
@@ -162,52 +77,31 @@ vinsynlib/
|
|
|
162
77
|
midi.py port listing, the shared error taxonomy, clean exit
|
|
163
78
|
conformance.py the checks a project runs against itself
|
|
164
79
|
devchecks.py checks that catch cross-project mistakes
|
|
80
|
+
backup.py the backup envelope: a versioned JSON container
|
|
81
|
+
catalog.py printed names, plus what has been read off the unit
|
|
82
|
+
livenames.py names read off the unit, kept between runs
|
|
83
|
+
render.py table and progress rendering, without Textual
|
|
84
|
+
undo.py the undo log: inspectable records, no threads or locks
|
|
165
85
|
ui/hints.py the legend widget
|
|
86
|
+
ui/browser.py BrowserApp, the AppProtocol implementation
|
|
87
|
+
ui/protocol.py the App contract screens depend on
|
|
88
|
+
ui/work.py worker infrastructure: busy gate, error set, idle-close
|
|
89
|
+
ui/confirm.py a generic yes/no confirmation modal
|
|
90
|
+
ui/prompt.py a one-line modal text prompt
|
|
91
|
+
ui/modals.py the shared modal screens: picker, search, report, rating
|
|
166
92
|
```
|
|
167
93
|
|
|
168
|
-
## Installing it, and who depends on it
|
|
169
|
-
|
|
170
|
-
This is a library, not a program, and it is **not on PyPI yet**. The ten tools
|
|
171
|
-
in the family depend on it, so it has to be a sibling checkout of whichever
|
|
172
|
-
one you are building:
|
|
173
|
-
|
|
174
|
-
```
|
|
175
|
-
git-repos/
|
|
176
|
-
vinsynlib/ <- this one
|
|
177
|
-
x5ded/ <- and the ten tools beside it
|
|
178
|
-
emorphed/ ensqsqed/ eosed/ kwsed/ ...
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
```sh
|
|
182
|
-
cd ../x5ded # or any sibling
|
|
183
|
-
git clone https://github.com/lentferj/vinsynlib.git ../vinsynlib
|
|
184
|
-
python3 -m venv .venv
|
|
185
|
-
.venv/bin/pip install --no-deps -e ../vinsynlib # --no-deps: its deps are theirs
|
|
186
|
-
.venv/bin/pip install -e .
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
Each of the ten writes those steps out in its own README, because a reader
|
|
190
|
-
starts from the tool and rarely from here. For projects that configure
|
|
191
|
-
`[tool.uv.sources]` pointing to this library, `uv sync` takes the path
|
|
192
|
-
from there, so the checkout only has to exist and neither `pip` line is needed.
|
|
193
|
-
For projects that work from an index (like the published tools), the explicit
|
|
194
|
-
`pip install -e ../vinsynlib` line remains necessary until the library is
|
|
195
|
-
published.
|
|
196
|
-
|
|
197
|
-
Publishing this to PyPI would replace all of it with an ordinary dependency
|
|
198
|
-
line. Until then, the sibling checkout *is* the install.
|
|
199
|
-
|
|
200
94
|
## Why it exists
|
|
201
95
|
|
|
202
96
|
Nine projects each grew a `config.py` (about 190 lines, 90-97% identical),
|
|
203
97
|
a `favorites.py` (about 620 lines, 85-100% identical), a `KeyHints` widget
|
|
204
|
-
and a `wrap_blocks` helper. Measured across the family: **
|
|
205
|
-
|
|
98
|
+
and a `wrap_blocks` helper. Measured across the family: **roughly 6,300
|
|
99
|
+
lines of that were duplicates that need not exist.**
|
|
206
100
|
|
|
207
101
|
Three of those copies had already drifted into bugs worth naming:
|
|
208
102
|
|
|
209
103
|
* `emorphed`'s `LICENSE` file opened with the words "nanosyned — Terminal
|
|
210
|
-
browser for the
|
|
104
|
+
browser for the E-mu Morpheus".
|
|
211
105
|
* `emorphed`'s `mypy` and `deptry` configuration still named the `nano`
|
|
212
106
|
module, and one function imported `nano.config` -- `nanosyned`'s package,
|
|
213
107
|
which is not installed beside it. That function worked in the project it
|
|
@@ -220,6 +114,68 @@ Three of those copies had already drifted into bugs worth naming:
|
|
|
220
114
|
None of these were visible in review. They were visible the moment there
|
|
221
115
|
was a second copy to compare against, which is what this library is.
|
|
222
116
|
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## ⚠️ Use at your own risk — back up first
|
|
120
|
+
|
|
121
|
+
vinsynlib is provided **as is, with absolutely no warranty and no liability**
|
|
122
|
+
for data loss or **hardware damage**. You assume all risk. Full terms:
|
|
123
|
+
[DISCLAIMER.md](DISCLAIMER.md).
|
|
124
|
+
|
|
125
|
+
Before you use this software, **make good, current backups of all your files** —
|
|
126
|
+
and of any existing banks on your instrument and storage media. These tools can
|
|
127
|
+
write to hardware and storage media; a mistake, a bug, or untested output could
|
|
128
|
+
overwrite or corrupt data, or be rejected by hardware. Always test on a spare
|
|
129
|
+
unit or emulator **before** connecting irreplaceable equipment.
|
|
130
|
+
|
|
131
|
+
## Installing it, and who depends on it
|
|
132
|
+
|
|
133
|
+
This is a library, not a program. It is published on PyPI — the current
|
|
134
|
+
release is 0.4.0 — so the ordinary way to depend on it is a dependency
|
|
135
|
+
line:
|
|
136
|
+
|
|
137
|
+
```toml
|
|
138
|
+
vinsynlib>=0.4.0
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
python3 -m pip install vinsynlib
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The library itself has no dependencies. The parts that need a terminal UI
|
|
146
|
+
or a MIDI backend are behind the `ui` and `midi` extras:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
python3 -m pip install "vinsynlib[ui,midi]"
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Ten projects in the family depend on it: the nine browsers above and
|
|
153
|
+
[k2kremote](https://github.com/lentferj/k2kremote). Each of them writes its
|
|
154
|
+
own install steps out in its README, because a reader starts from the tool
|
|
155
|
+
and rarely from here.
|
|
156
|
+
|
|
157
|
+
**Working on the library itself.** To develop against a checkout rather
|
|
158
|
+
than the published release, put it beside the project that uses it and
|
|
159
|
+
install it editable:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
git-repos/
|
|
163
|
+
vinsynlib/ <- this one
|
|
164
|
+
x5ded/ <- a sibling, and the other tools beside it
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
cd ../x5ded # or any sibling
|
|
169
|
+
git clone https://github.com/lentferj/vinsynlib.git ../vinsynlib
|
|
170
|
+
python3 -m venv .venv
|
|
171
|
+
.venv/bin/pip install --no-deps -e ../vinsynlib # --no-deps: its deps are theirs
|
|
172
|
+
.venv/bin/pip install -e .
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
For projects that configure `[tool.uv.sources]` pointing to this library,
|
|
176
|
+
`uv sync` takes the path from there, so the checkout only has to exist and
|
|
177
|
+
neither `pip` line is needed.
|
|
178
|
+
|
|
223
179
|
## Using it
|
|
224
180
|
|
|
225
181
|
```python
|
|
@@ -245,20 +201,6 @@ parser = cli.make_parser("x5cli", "Browse a Korg X5D's sounds.")
|
|
|
245
201
|
cli.add_common_arguments(parser, port=True, scan=True, channel=True)
|
|
246
202
|
```
|
|
247
203
|
|
|
248
|
-
## Development
|
|
249
|
-
|
|
250
|
-
```console
|
|
251
|
-
$ uv venv && uv pip install -e ".[ui,midi]" && uv pip install \
|
|
252
|
-
pytest pytest-cov mypy ruff vulture deptry detect-secrets pip-audit
|
|
253
|
-
$ make check
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
`make check` runs the whole gate in order and stops at the first failure:
|
|
257
|
-
ruff, mypy in strict mode, the test suite with coverage, then vulture,
|
|
258
|
-
deptry and pip-audit.
|
|
259
|
-
|
|
260
|
-
> **Legal:** [DISCLAIMER.md](DISCLAIMER.md) · [LICENSE](LICENSE)
|
|
261
|
-
|
|
262
204
|
## Where the rules are written down
|
|
263
205
|
|
|
264
206
|
**[docs/UX-SPEC.md](docs/UX-SPEC.md)** is the contract: terminology, the
|
|
@@ -282,3 +224,89 @@ mistranslation is the difference between finding a sound and not.
|
|
|
282
224
|
first lives in the working directory and is safe to delete. The second
|
|
283
225
|
lives in the platform data directory, is keyed on the slot rather than the
|
|
284
226
|
name, and is the one file here worth backing up.
|
|
227
|
+
|
|
228
|
+
## Development
|
|
229
|
+
|
|
230
|
+
```console
|
|
231
|
+
$ uv venv && uv pip install -e ".[ui,midi]" && uv pip install \
|
|
232
|
+
pytest pytest-cov mypy ruff vulture deptry detect-secrets pip-audit
|
|
233
|
+
$ make check
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
`make check` runs the whole gate in order and stops at the first failure:
|
|
237
|
+
ruff, mypy in strict mode, the test suite with coverage, then vulture,
|
|
238
|
+
deptry and pip-audit.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Support this project
|
|
243
|
+
|
|
244
|
+
vinsynlib is free software and always will be. Nothing is behind a paywall,
|
|
245
|
+
no feature is withheld, and none of what follows changes that.
|
|
246
|
+
|
|
247
|
+
But if it has been useful — if it saved you an evening of mapping zones
|
|
248
|
+
by hand, or got a library onto a machine that had no way of reading it, or
|
|
249
|
+
**best of all, if it has your vintage instrument switched on and in use more often
|
|
250
|
+
than it was, and you are having more fun with it** — then please consider
|
|
251
|
+
supporting the work.
|
|
252
|
+
|
|
253
|
+
**Because here is what it has actually cost:**
|
|
254
|
+
|
|
255
|
+
- **Real machines on a real bench.** Much of what these tools know about these
|
|
256
|
+
formats was measured on hardware rather than read anywhere, because for most
|
|
257
|
+
of it there is nowhere to read it. That needs the machines — the instruments
|
|
258
|
+
themselves — and it puts hours of wear on hardware that has been locked up and
|
|
259
|
+
recovered more than once in the course of it. Some of these instruments were
|
|
260
|
+
bought specifically to add and verify a format; the others were already here,
|
|
261
|
+
because the person doing this is a vintage instrument enthusiast first and the
|
|
262
|
+
projects exist because the instruments were in the room.
|
|
263
|
+
- **Dozens — realistically hundreds — of hours of human time.** Format
|
|
264
|
+
reverse-engineering is slow: measure, be wrong, measure again. A single
|
|
265
|
+
parameter law in one of the projects can represent an evening at the bench.
|
|
266
|
+
- **AI assistance, which is a paid service**, used heavily throughout and not
|
|
267
|
+
cheap at this volume.
|
|
268
|
+
|
|
269
|
+
**This is support, not a donation — and the distinction is a legal one, not a
|
|
270
|
+
turn of phrase.** The maintainer is based in Germany, where payments like these
|
|
271
|
+
are *not* `Spenden` in the tax sense: they count as **taxable income** for the
|
|
272
|
+
recipient and are **not tax-deductible** for the giver. So this section is
|
|
273
|
+
titled *Support*, deliberately, and no receipt for tax purposes can be issued.
|
|
274
|
+
(That is a statement of how it is handled here, not tax advice.)
|
|
275
|
+
|
|
276
|
+
If the project saved you the work, you can support it through
|
|
277
|
+
**[GitHub Sponsors](https://github.com/sponsors/lentferj)** — the *Sponsor*
|
|
278
|
+
button at the top of the repository. Payment is handled entirely by GitHub and
|
|
279
|
+
Stripe, so bank and tax details are never handed to the person paying.
|
|
280
|
+
|
|
281
|
+
**Support is not expected, and it is not the only currency.**
|
|
282
|
+
|
|
283
|
+
- **Bug reports** — ideally with the bank, preset or disk image that produced
|
|
284
|
+
them. A tool's failures are usually specific to one file rather than
|
|
285
|
+
general, and without that file they are very hard to reproduce.
|
|
286
|
+
- **Confirmations from hardware that is not on this bench**, which matters more
|
|
287
|
+
here than for a single-machine tool. These tools write for whole *families*
|
|
288
|
+
of instruments, and the bench holds only a subset. Whether a variant accepts
|
|
289
|
+
what we write is genuinely unknown, and several notes say "on this unit" for
|
|
290
|
+
that reason. A "loads fine here too", or a "no, mine refuses it", is worth a
|
|
291
|
+
great deal.
|
|
292
|
+
- **Corrections to the reverse-engineering notes.** The wrong turns are
|
|
293
|
+
recorded next to the findings — in this repository's `TODO.md`, and in each
|
|
294
|
+
project's own `docs/RESOLUTION_NOTES.md` — retractions included, because a
|
|
295
|
+
finding that was withdrawn is as useful as one that stood. If any of it is
|
|
296
|
+
wrong in a way that is still costing someone time, saying so improves the
|
|
297
|
+
record.
|
|
298
|
+
|
|
299
|
+
## AI assistance & human authorship
|
|
300
|
+
|
|
301
|
+
vinsynlib was built by its human author together with AI assistance. The
|
|
302
|
+
**ideas, the project vision, and every feature** came from the human author;
|
|
303
|
+
AI assisted with **writing the code and analyzing the binary formats**.
|
|
304
|
+
Crucially, the **reverse engineering rests on hands-on human work** — all testing
|
|
305
|
+
and verification on real hardware, creating the reference images/banks on those
|
|
306
|
+
instruments (disk saves, SysEx probes), and aural A/B comparison of presets —
|
|
307
|
+
which is what makes the results correct.
|
|
308
|
+
Full account in [DISCLAIMER.md](DISCLAIMER.md).
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
> **Legal:** [DISCLAIMER.md](DISCLAIMER.md) · [LICENSE](LICENSE)
|