fiioctl 0.1.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.
- fiioctl-0.1.0/LICENSE +21 -0
- fiioctl-0.1.0/PKG-INFO +384 -0
- fiioctl-0.1.0/README.md +341 -0
- fiioctl-0.1.0/fiioctl/__init__.py +3 -0
- fiioctl-0.1.0/fiioctl/__main__.py +5 -0
- fiioctl-0.1.0/fiioctl/cli.py +851 -0
- fiioctl-0.1.0/fiioctl/cloud.py +393 -0
- fiioctl-0.1.0/fiioctl/curve.py +128 -0
- fiioctl-0.1.0/fiioctl/device.py +367 -0
- fiioctl-0.1.0/fiioctl/eqdb.py +169 -0
- fiioctl-0.1.0/fiioctl/proto.py +150 -0
- fiioctl-0.1.0/fiioctl/registry.py +240 -0
- fiioctl-0.1.0/fiioctl/ui.py +871 -0
- fiioctl-0.1.0/fiioctl.egg-info/PKG-INFO +384 -0
- fiioctl-0.1.0/fiioctl.egg-info/SOURCES.txt +24 -0
- fiioctl-0.1.0/fiioctl.egg-info/dependency_links.txt +1 -0
- fiioctl-0.1.0/fiioctl.egg-info/entry_points.txt +2 -0
- fiioctl-0.1.0/fiioctl.egg-info/requires.txt +18 -0
- fiioctl-0.1.0/fiioctl.egg-info/top_level.txt +1 -0
- fiioctl-0.1.0/pyproject.toml +79 -0
- fiioctl-0.1.0/setup.cfg +4 -0
- fiioctl-0.1.0/tests/test_cli.py +172 -0
- fiioctl-0.1.0/tests/test_cloud.py +161 -0
- fiioctl-0.1.0/tests/test_curve.py +92 -0
- fiioctl-0.1.0/tests/test_proto.py +404 -0
- fiioctl-0.1.0/tests/test_ui.py +525 -0
fiioctl-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ethan Barclay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
fiioctl-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fiioctl
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Minimal, extensible CLI for controlling FiiO USB DACs over HID
|
|
5
|
+
Author: Ethan Barclay
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ethanbarclay/fiioctl
|
|
8
|
+
Project-URL: Repository, https://github.com/ethanbarclay/fiioctl
|
|
9
|
+
Project-URL: Issues, https://github.com/ethanbarclay/fiioctl/issues
|
|
10
|
+
Project-URL: Protocol, https://github.com/ethanbarclay/fiioctl/blob/main/docs/PROTOCOL.md
|
|
11
|
+
Keywords: fiio,usb-dac,hid,equalizer,parametric-eq,autoeq,audio
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
24
|
+
Classifier: Topic :: System :: Hardware :: Universal Serial Bus (USB)
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: hidapi>=0.15
|
|
29
|
+
Provides-Extra: ui
|
|
30
|
+
Requires-Dist: textual>=8.0; extra == "ui"
|
|
31
|
+
Provides-Extra: cloud
|
|
32
|
+
Requires-Dist: cryptography>=44; extra == "cloud"
|
|
33
|
+
Provides-Extra: all
|
|
34
|
+
Requires-Dist: textual>=8.0; extra == "all"
|
|
35
|
+
Requires-Dist: cryptography>=44; extra == "all"
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=9; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-asyncio>=1.4; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-cov>=7; extra == "dev"
|
|
40
|
+
Requires-Dist: textual>=8.0; extra == "dev"
|
|
41
|
+
Requires-Dist: cryptography>=44; extra == "dev"
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
|
|
44
|
+
# fiioctl
|
|
45
|
+
|
|
46
|
+
[](https://github.com/ethanbarclay/fiioctl/actions/workflows/ci.yml)
|
|
47
|
+
|
|
48
|
+
Control FiiO USB DACs from the command line on Linux, macOS and Windows. A small,
|
|
49
|
+
declarative reimplementation of what the FiiO Control web app does over WebHID,
|
|
50
|
+
built to be scripted.
|
|
51
|
+
|
|
52
|
+
The CLI core is ~1500 lines of Python with a single runtime dependency
|
|
53
|
+
(`hidapi`) and no daemon. The terminal UI and FiiO-catalogue support are optional
|
|
54
|
+
extras on top.
|
|
55
|
+
|
|
56
|
+
Session output below is illustrative; see
|
|
57
|
+
[Verification status](#verification-status) for what has actually been run.
|
|
58
|
+
|
|
59
|
+
```console
|
|
60
|
+
$ fiioctl info
|
|
61
|
+
product FIIO KA15
|
|
62
|
+
matched_profile FIIO KA15
|
|
63
|
+
report_id 7
|
|
64
|
+
firmware 1.14
|
|
65
|
+
bands 10
|
|
66
|
+
capabilities eq, peq, preset-names, volume, filter, balance
|
|
67
|
+
|
|
68
|
+
$ fiioctl eq search "hd 650"
|
|
69
|
+
0 Sennheiser HD 650 [oratory1990 / over-ear]
|
|
70
|
+
1 Sennheiser HD 650 [crinacle / GRAS 43AG-7 over-ear]
|
|
71
|
+
2 Sennheiser HD 650 [Kuulokenurkka / over-ear]
|
|
72
|
+
|
|
73
|
+
$ fiioctl eq apply "hd 650" --slot user1 --save
|
|
74
|
+
applied 'Sennheiser HD 650' (oratory1990): 10 bands, preamp -5.8 dB
|
|
75
|
+
|
|
76
|
+
$ fiioctl peq show
|
|
77
|
+
global gain -5.8 dB
|
|
78
|
+
0 105 Hz +5.5 dB Q 0.70 low-shelf
|
|
79
|
+
1 180 Hz -3.3 dB Q 0.57 peak
|
|
80
|
+
...
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Install
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pipx install . # or: pip install -e .
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The one dependency is **`hidapi`** (cython-hidapi), whose wheels bundle the
|
|
90
|
+
hidapi library, so there is nothing to install by hand on any platform.
|
|
91
|
+
|
|
92
|
+
> **Watch out for the `hid` package.** A *different* PyPI distribution named
|
|
93
|
+
> `hid` also installs a top-level `hid` module, with an incompatible API and no
|
|
94
|
+
> bundled library. Its package directory shadows cython-hidapi's module, and you
|
|
95
|
+
> get `ImportError: Unable to load any of the following libraries`. If you hit
|
|
96
|
+
> that: `pip uninstall hid`.
|
|
97
|
+
|
|
98
|
+
If you use **pyenv-win**, console scripts land in the version's `Scripts`
|
|
99
|
+
directory, which is not on `PATH` — run `pyenv rehash` once after installing to
|
|
100
|
+
generate the shim, otherwise `fiioctl` is "not recognized".
|
|
101
|
+
|
|
102
|
+
On Linux, allow non-root access to the device:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
sudo install -m644 packaging/99-fiio.rules /etc/udev/rules.d/
|
|
106
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then re-plug the DAC. On macOS and Windows no setup is needed.
|
|
110
|
+
|
|
111
|
+
## What it does
|
|
112
|
+
|
|
113
|
+
| Area | Commands |
|
|
114
|
+
|---|---|
|
|
115
|
+
| Discovery | `fiioctl devices`, `fiioctl info`, `fiioctl state` |
|
|
116
|
+
| Any setting | `fiioctl get <name>`, `fiioctl set <name> <value>` |
|
|
117
|
+
| EQ presets | `fiioctl eq preset [name]`, `eq name <slot> [NAME]`, `eq save [slot]` |
|
|
118
|
+
| Headphone EQ | `fiioctl eq search <query>`, `fiioctl eq apply <query> [--slot] [--save]` |
|
|
119
|
+
| Parametric EQ | `fiioctl peq show`, `peq set <band> --freq --gain --q --filter`, `peq import/export`, `peq clear` |
|
|
120
|
+
| FiiO catalogue | `fiioctl cloud list`, `cloud show <n>`, `cloud apply <n>` |
|
|
121
|
+
| Terminal UI | `fiioctl ui` |
|
|
122
|
+
| Escape hatch | `fiioctl raw <cmd> [hex] [--read]`, global `--trace` |
|
|
123
|
+
| Machine use | `fiioctl schema`, `fiioctl batch`, `--json` on everything |
|
|
124
|
+
|
|
125
|
+
`fiioctl get`/`set` cover every decoded command — volume, volume limit, line-out
|
|
126
|
+
switch, channel balance, DAC filter, EQ master switch, EQ global gain, indicator
|
|
127
|
+
LED, screen orientation, and the microphone controls on devices that have one.
|
|
128
|
+
Run `fiioctl set --help` for the current list.
|
|
129
|
+
|
|
130
|
+
## Terminal UI
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pip install 'fiioctl[all]'
|
|
134
|
+
fiioctl ui
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Four pages down the left — **Device**, **Equaliser**, **EQ slots**, **Library** —
|
|
138
|
+
switched with `1`–`4`. One rule everywhere: **arrow to a thing, press `+` or `-`
|
|
139
|
+
to change it.** No buttons, no forms to submit, and the hint line at the bottom
|
|
140
|
+
always names what is selected and what the step is, so there is nothing to
|
|
141
|
+
memorise.
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
1 Device │ # frequency gain Q filter global gain -7.0 dB
|
|
145
|
+
2 Equaliser │ 0 32 Hz +3.0 dB 0.71 peak +6 ┤ ━━━
|
|
146
|
+
3 EQ slots │ 1 64 Hz +3.0 dB 0.71 peak ┤ ━━━ ━━━
|
|
147
|
+
4 Library │ 2 125 Hz +2.5 dB 0.71 peak ┤━━ ━ ━ ━━━
|
|
148
|
+
│ 3 250 Hz -0.5 dB 0.71 peak 0 ┼────────────━───━━─────━━━━━━━
|
|
149
|
+
│ 4 500 Hz -2.5 dB 0.71 peak ┤ ━━━━━
|
|
150
|
+
─────────────────────────────────────────────────────────────────────────────────────────────
|
|
151
|
+
selected band 2 · gain = +2.5 dB
|
|
152
|
+
+ / - change by 0.5 dB PgUp / PgDn by 5 dB Tab switch 1-4 pages ? keys
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **Device** — every onboard setting the model exposes: volume, volume limit,
|
|
156
|
+
line-out switch, channel balance, DAC filter, EQ preset, global gain, and the
|
|
157
|
+
LED/screen/microphone controls on devices that have them.
|
|
158
|
+
- **Equaliser** — the band table with a live response curve, computed from the
|
|
159
|
+
same RBJ biquads the official app uses.
|
|
160
|
+
- **EQ slots** — every preset slot with its stored name and which one is active.
|
|
161
|
+
`Enter` loads one, `n` renames a user slot, `s` saves the current EQ into it.
|
|
162
|
+
- **Library** — search AutoEq *and* FiiO's catalogue together, with a curve
|
|
163
|
+
preview for the highlighted result before you commit it.
|
|
164
|
+
|
|
165
|
+
`u` undoes the last write, `r` re-reads from the device, `?` lists every key.
|
|
166
|
+
|
|
167
|
+
## FiiO's own preset catalogue
|
|
168
|
+
|
|
169
|
+
`fiioctl cloud` reads the presets FiiO and other users publish for your exact
|
|
170
|
+
model — the same lists the official web app shows, anonymously and read-only:
|
|
171
|
+
|
|
172
|
+
```console
|
|
173
|
+
$ fiioctl cloud list
|
|
174
|
+
0 FH3 FOR KA15 [fiio-official] 10 bands, preamp +8.0 dB, 27 dl
|
|
175
|
+
1 FF5 FOR KA15 [fiio-official] 10 bands, preamp +6.0 dB, 26 dl
|
|
176
|
+
2 FT1 FOR KA15 [fiio-official] 10 bands, preamp -6.0 dB, 20 dl
|
|
177
|
+
...
|
|
178
|
+
9 Simgot EW300 to VDSF Target [fiio-community] by ... 10 bands, 10 dl
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`cloud show <n>` prints the bands and curve; `cloud apply <n>` writes it. Needs
|
|
182
|
+
`pip install 'fiioctl[cloud]'`. Protocol details — including the AES/RSA envelope
|
|
183
|
+
and FiiO's measurement service — are in [docs/CATALOGUE.md](docs/CATALOGUE.md).
|
|
184
|
+
|
|
185
|
+
## Headphone EQ profiles
|
|
186
|
+
|
|
187
|
+
Profiles come from [AutoEq](https://github.com/jaakkopasanen/AutoEq) — the same
|
|
188
|
+
measurement data FiiO's own app credits as its source. The index (~850 KB) is
|
|
189
|
+
cached locally, so search is instant and works offline after the first run.
|
|
190
|
+
`--refresh` is not needed; the cache expires after 30 days.
|
|
191
|
+
|
|
192
|
+
`eq apply` maps a profile onto the device's bands, clamps gains to what the
|
|
193
|
+
hardware accepts, flattens any bands the profile does not use, and tells you if
|
|
194
|
+
the profile had more bands than the device has.
|
|
195
|
+
|
|
196
|
+
AutoEq does not carry everything — Drop collaborations such as the DT 177X Go are
|
|
197
|
+
absent from it. For those, use `fiioctl autoeq`, below.
|
|
198
|
+
|
|
199
|
+
## FiiO's measurement database (~4500 headphones)
|
|
200
|
+
|
|
201
|
+
Bigger than AutoEq's public set, and it includes per-variant measurements. This
|
|
202
|
+
runs the same server-side AutoEq the official web app uses, so the result matches
|
|
203
|
+
what that UI would produce:
|
|
204
|
+
|
|
205
|
+
```console
|
|
206
|
+
$ fiioctl autoeq refresh
|
|
207
|
+
refreshed: 4544 measurements, 4578 targets
|
|
208
|
+
|
|
209
|
+
$ fiioctl autoeq search "dt177x go"
|
|
210
|
+
714 Beyerdynamic DT 177X Go [leather earpads] — oratory1990
|
|
211
|
+
715 Beyerdynamic DT 177X Go [velour earpads] — oratory1990
|
|
212
|
+
|
|
213
|
+
$ fiioctl autoeq show 714
|
|
214
|
+
Beyerdynamic DT 177X Go (leather earpads) [fiio-autoeq/oratory1990]
|
|
215
|
+
target: Harman over-ear 2018 (id 6)
|
|
216
|
+
preamp -6.6 dB
|
|
217
|
+
105 Hz -7.5 dB Q 0.70 low-shelf
|
|
218
|
+
133 Hz -5.9 dB Q 1.15 peak
|
|
219
|
+
...
|
|
220
|
+
10000 Hz +2.4 dB Q 0.70 high-shelf
|
|
221
|
+
|
|
222
|
+
$ fiioctl autoeq apply 714 --save
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
The target curve is chosen the way FiiO chooses it — matching the measurement's
|
|
226
|
+
rig and form factor against their own recommendation table — or pick one yourself
|
|
227
|
+
with `--target <id>` after browsing `fiioctl autoeq targets harman`.
|
|
228
|
+
|
|
229
|
+
The two indexes (~800 KB) are cached locally for 14 days; `autoeq refresh`
|
|
230
|
+
re-downloads them. Individual frequency-response curves are fetched lazily and
|
|
231
|
+
then cached, rather than mirroring ~90 MB of data nobody asked for.
|
|
232
|
+
|
|
233
|
+
## Scripting and agents
|
|
234
|
+
|
|
235
|
+
Every command takes `--json` and returns a stable exit code: `0` ok, `2` usage,
|
|
236
|
+
`3` device error, `4` data error.
|
|
237
|
+
|
|
238
|
+
`fiioctl schema` dumps the entire model — framing, every command with its ID,
|
|
239
|
+
codec, range and capability, the per-device registry, and the batch protocol —
|
|
240
|
+
as one JSON document. That is the intended way for an agent to discover what it
|
|
241
|
+
can do, instead of parsing `--help`.
|
|
242
|
+
|
|
243
|
+
For many operations in a row, `fiioctl batch` reads one JSON object per line and
|
|
244
|
+
keeps the device open, which removes both interpreter startup and the
|
|
245
|
+
~10–50 ms device-open cost from each step:
|
|
246
|
+
|
|
247
|
+
```console
|
|
248
|
+
$ printf '%s\n' \
|
|
249
|
+
'{"op":"set","name":"eq-gain","value":-6}' \
|
|
250
|
+
'{"op":"band","index":0,"freq":105,"gain":5.5,"q":0.7,"filter":"low-shelf"}' \
|
|
251
|
+
'{"op":"get","name":"volume"}' | fiioctl batch
|
|
252
|
+
{"ok": true, "value": -6.0, "request": "..."}
|
|
253
|
+
{"ok": true, "request": "..."}
|
|
254
|
+
{"ok": true, "value": 42, "request": "..."}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`--dry-run` builds and prints packets without writing, and works with no device
|
|
258
|
+
attached — useful for testing and for inspecting what a command would send:
|
|
259
|
+
|
|
260
|
+
```console
|
|
261
|
+
$ fiioctl --dry-run peq set 2 --freq 9140 --gain 5.6 --q 3.46
|
|
262
|
+
TX 07 aa 0a 00 00 15 08 02 00 38 23 b4 01 5a 00 00 ee
|
|
263
|
+
band 2: 9140 Hz +5.6 dB Q 3.46 peak
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Extending it
|
|
267
|
+
|
|
268
|
+
Adding a decoded command is one line in `fiioctl/registry.py`:
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
"my-setting": Cmd(42, "u8", help="..."),
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Adding a device is one entry in the same file's `DEVICES` table — report ID,
|
|
275
|
+
command pacing, gain range, preset map, renameable slots. No code changes.
|
|
276
|
+
|
|
277
|
+
Undecoded commands are listed in `registry.UNMAPPED` and reachable right away:
|
|
278
|
+
|
|
279
|
+
```console
|
|
280
|
+
$ fiioctl raw 27 # send cmd 27 with no payload
|
|
281
|
+
$ fiioctl raw 53 --read # GET cmd 53 and show the reply bytes
|
|
282
|
+
$ fiioctl --trace state # watch every packet
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Layout
|
|
286
|
+
|
|
287
|
+
```
|
|
288
|
+
core (no optional dependencies)
|
|
289
|
+
fiioctl/proto.py framing + value codecs 77
|
|
290
|
+
fiioctl/curve.py RBJ biquads + text plot 102
|
|
291
|
+
fiioctl/registry.py command + device data 116
|
|
292
|
+
fiioctl/eqdb.py AutoEq search, PEQ files 117
|
|
293
|
+
fiioctl/device.py HID transport, pacing 174
|
|
294
|
+
fiioctl/cli.py argparse surface 499
|
|
295
|
+
optional
|
|
296
|
+
fiioctl/ui.py terminal UI [ui] 648
|
|
297
|
+
fiioctl/cloud.py FiiO catalogue [cloud] 124
|
|
298
|
+
|
|
299
|
+
docs/PROTOCOL.md the reverse-engineered HID protocol
|
|
300
|
+
docs/CATALOGUE.md FiiO's online services
|
|
301
|
+
packaging/ Linux udev rule
|
|
302
|
+
tests/ 61 tests, no hardware or network needed
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Line counts exclude blanks, comments and docstrings.
|
|
306
|
+
|
|
307
|
+
## Verification status
|
|
308
|
+
|
|
309
|
+
Be aware of what has and has not been checked:
|
|
310
|
+
|
|
311
|
+
- **Verified on hardware** (KA15, firmware 1.1.6): device discovery, the reply
|
|
312
|
+
parser, `info`, `state`, `get`, `peq show`, preset-name reads, and the write
|
|
313
|
+
path.
|
|
314
|
+
- **Verified against FiiO's live services**: `cloud list` / `cloud show`
|
|
315
|
+
(39 presets for the KA15) and `autoeq refresh` / `search` / `show`
|
|
316
|
+
(4544 measurements, 4578 targets, server-side equalisation). Reading preset 6 returned a coherent octave-spaced hiphop curve and the
|
|
317
|
+
user slots decoded as real names (`FD15`, `FF5`, `FH3`), which together confirm
|
|
318
|
+
the band codec and the slot-offset-of-7 quirk.
|
|
319
|
+
- **Verified against the bundle**: every packet `fiioctl` builds was compared
|
|
320
|
+
byte-for-byte with the official app's own encoders, and the codecs round-trip
|
|
321
|
+
under `pytest` (`tests/test_proto.py`). AutoEq search and profile parsing run
|
|
322
|
+
against live data.
|
|
323
|
+
- **Write path verified on hardware**: `autoeq apply … --save` wrote all ten
|
|
324
|
+
bands and read back identically, `eq save` persisted to a user slot, and
|
|
325
|
+
`eq name` round-tripped. Round-tripping values through the device is also what
|
|
326
|
+
turned up two defects since fixed — the global gain's whole-decibel
|
|
327
|
+
quantization and the uncleared preset-name field (both in
|
|
328
|
+
[docs/PROTOCOL.md](docs/PROTOCOL.md)).
|
|
329
|
+
- **Not yet exercised**: `factory-reset`, and `peq clear` on a device with
|
|
330
|
+
settings worth keeping.
|
|
331
|
+
- **Best-effort**: the non-KA15 entries in `DEVICES`, transcribed from the app's
|
|
332
|
+
per-device tables rather than observed. `fiioctl info` reports
|
|
333
|
+
`verified_on_hardware` so you know which you are relying on.
|
|
334
|
+
|
|
335
|
+
### Devices it cannot drive
|
|
336
|
+
|
|
337
|
+
FiiO's own app uses three different transports, and this project implements one
|
|
338
|
+
of them — the shared HID command set. Two groups are therefore out of reach, and
|
|
339
|
+
`fiioctl` says so rather than failing obscurely:
|
|
340
|
+
|
|
341
|
+
| | Devices |
|
|
342
|
+
|---|---|
|
|
343
|
+
| different protocol (adapter) | KG13, BTR15, JadeAudio Trustblu, FG3, JK13, SNOWSKY GAMDONG, JD1 Gaming |
|
|
344
|
+
| USB CDC serial, not HID | K15 (confirmed); K17/K19 possibly |
|
|
345
|
+
|
|
346
|
+
```console
|
|
347
|
+
$ fiioctl info
|
|
348
|
+
error: FIIO BTR15: the official app drives this model through a different
|
|
349
|
+
protocol, which fiioctl does not implement. See docs/PROTOCOL.md.
|
|
350
|
+
Pass --force to talk to it anyway as if it were an HID device.
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Everything else the app supports uses the same command numbers, so volume, EQ,
|
|
354
|
+
presets, filter and balance should work — see
|
|
355
|
+
[docs/PROTOCOL.md](docs/PROTOCOL.md) for the evidence.
|
|
356
|
+
|
|
357
|
+
Use `--dry-run` to inspect packets without writing, and `--trace` to watch real
|
|
358
|
+
traffic. `fiioctl devices` and `fiioctl info` report which profile was matched.
|
|
359
|
+
|
|
360
|
+
## TODO
|
|
361
|
+
|
|
362
|
+
- **Firmware flashing** (v2). The app's `update-firmware` / `kt1213-update`
|
|
363
|
+
chunks implement it. Left out of v1 deliberately: it is the only operation that
|
|
364
|
+
can brick the device, so it needs its own verification pass rather than being
|
|
365
|
+
bundled in with settings control.
|
|
366
|
+
- Bluetooth controls (codec selection, pairing) for the BTR/BT11 devices — the
|
|
367
|
+
commands live in the app's `bt11-cmd` and `tengtai-controller` chunks.
|
|
368
|
+
- The dynamics processor (compressor/limiter) commands, 53–57.
|
|
369
|
+
|
|
370
|
+
## Credits
|
|
371
|
+
|
|
372
|
+
Protocol derived from the FiiO Control web app as vendored by
|
|
373
|
+
[Ircama/fiiocontrol](https://github.com/Ircama/fiiocontrol) and verified against
|
|
374
|
+
hardware. Headphone measurements by
|
|
375
|
+
[AutoEq](https://github.com/jaakkopasanen/AutoEq).
|
|
376
|
+
|
|
377
|
+
MIT licensed — see [LICENSE](LICENSE), and [ATTRIBUTION.md](ATTRIBUTION.md) for
|
|
378
|
+
full provenance and the licences of everything consulted. Not affiliated with or
|
|
379
|
+
endorsed by FiiO.
|
|
380
|
+
|
|
381
|
+
[CHANGELOG.md](CHANGELOG.md) covers what changed per release.
|
|
382
|
+
[SECURITY.md](SECURITY.md) covers how to report a vulnerability, what this tool
|
|
383
|
+
touches, and why the AES-ECB in the catalogue client is FiiO's choice rather
|
|
384
|
+
than ours.
|