Repository navigation
Expand file tree
/
Copy pathoutput.yml
More file actions
493 lines (474 loc) · 17.7 KB
/
Copy pathoutput.yml
File metadata and controls
493 lines (474 loc) · 17.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# The <output> block, modeled completely.
#
# Sources compared for every entry below:
# Android PhyphoxFile.java: outputBlockParser, AudioOutputPluginBlockParser,
# FlashlightBlockParser, and the bluetooth io parser (b4564695)
# Bluetooth/ConversionsOutput.java, ConversionsConfig.java
# iOS Serialization/Handlers/OutputElementHandler.swift (a0643729)
# docs docs/file-format/output.md, bluetooth-low-energy.md
#
# `agreement:` records what that comparison found. See README.md.
#
# Note on <bluetooth>: the element appears in BOTH the input and the output
# block and they are different elements. The one here writes buffer values to a
# device; the one in input.yml reads from it. They share the device-matching
# attributes and the config child, and differ in everything else - this one has
# no mode, rate or subscribeOnStart, and its data child is <input> rather than
# <output>.
block: output
since: "1.0"
summary: >-
Hardware the experiment drives: the speaker, the flashlight, and Bluetooth
devices written to rather than read from.
elements:
- name: output
parent: phyphox
since: "1.0"
summary: Container for all hardware outputs.
attributes: []
children: [audio, bluetooth, flashlight]
# ------------------------------------------------------------------ audio --
- name: audio
parent: output
since: "1.0"
summary: The speaker.
children: [input, tone, noise]
attributes:
- name: rate
type: integer
default: 48000
exclusive_minimum: 0 # a sample rate of zero or less is not a rate
unit: Hz
summary: Sample rate of the generated signal.
agreement: agreed
- name: loop
type: boolean
default: false
summary: Repeat the buffer instead of playing it once.
description: >-
Applies to all sources of the output together. Playback is
triggered at the end of every analysis cycle, and loop also decides
what such a trigger does to a sound that is still playing. Without
loop, a trigger starts the output over from its beginning: the
direct source from its first sample and the duration of tone and
noise generators from zero, whether the previous playback had
finished or not. With loop, the duration of tone and noise
generators is ignored and a trigger while the output is playing
changes nothing, so a looped waveform of any length plays
continuously. In both cases, changed data or parameters are picked
up with the next block of audio the app generates, which may be
heard a fraction of a second later. The end of a one-shot output
follows the data as well: a direct source that grows while it
plays goes on to its new end, one that shrinks stops earlier, and
a changed tone or noise duration applies from the next block.
agreement: agreed
- name: normalize
type: boolean
default: false
since: "1.10"
summary: Normalize the amplitude of all inputs.
agreement: agreed
# <input> appears at two levels and means different things. Directly under
# <audio> it is the waveform itself; inside <tone> or <noise> it drives one
# parameter of that generator. Android handles all three with the same code,
# distinguishing them by whether `parameter` is set and whether a generator is
# open; iOS registers a separate handler under each.
- name: input
parent: audio
since: "1.0"
summary: >-
The waveform, played from the data container at the end of each
analysis pass. Values run from -1 to +1 and the buffer's length sets the
duration. Without loop, each pass starts the waveform over from its
first sample; with loop, it repeats continuously and a pass that ends
while it plays changes nothing - new buffer contents are picked up with
the next block of audio. The mono signal plays identically on both
stereo channels and the element takes no parameter inputs. Only one
direct source is supported.
text: Name of the data container holding the waveform.
agreement: agreed
attributes: []
# The type attribute was removed from the direct input on 2026-08-19:
# type="value" never makes sense for a waveform. Android used to honor it
# (fixed 2026-08-20); iOS never read it.
- name: tone
parent: audio
since: "1.10"
summary: >-
A parametric tone generator, driven by the input elements inside it. Each
tone tracks the phase of its wave so that changing the frequency does not
click. Several are allowed.
children: [input]
attributes:
- name: waveform
type: enum
values: [sine, square, sawtooth]
default: sine
since: "1.19"
summary: Shape of the generated wave.
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
- name: input
parent: tone
since: "1.10"
summary: Drives one parameter of the tone generator.
text: Name of a data container, or a literal number when type is value.
attributes:
- name: parameter
type: enum
values: [pan, amplitude, duration, frequency]
summary: Which parameter of the generator this input drives.
value_notes:
pan: >-
Stereo position, from -1 (left) through 0 (center) to +1 (right).
A centered signal plays at full amplitude on both channels, and
panning reduces the opposite channel rather than boosting the near
one. Available from file format 1.20.
amplitude: >-
Amplitude, from 0.0 (silent) to 1.0 (the loudest without clipping).
duration: Duration of the generated signal, in seconds.
frequency: >-
Frequency of the tone, in Hz.
agreement: agreed
- name: type
type: enum
values: [buffer, value]
default: buffer
summary: Whether the text names a data container or is a literal value.
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
- name: noise
parent: audio
since: "1.10"
summary: >-
A white-noise generator, driven by the input elements inside it. Only one
is supported.
children: [input]
attributes: []
- name: input
parent: noise
since: "1.10"
summary: >-
Drives one parameter of the noise generator.
text: Name of a data container, or a literal number when type is value.
attributes:
- name: parameter
type: enum
values: [pan, amplitude, duration]
summary: Which parameter of the generator this input drives.
value_notes:
pan: >-
Stereo position, from -1 (left) through 0 (center) to +1 (right),
like on the tone generator. Available from file format 1.20.
amplitude: >-
Amplitude, from 0.0 (silent) to 1.0 (the loudest without clipping).
duration: Duration of the generated signal, in seconds.
agreement: agreed
note: >-
frequency was listed here until 2026-08-19 with a "does not apply"
remark, but both parsers have always rejected it at load - Android
via AudioOutputPluginNoise.setParameter returning false, iOS via the
explicit throw in PhyphoxElementHandler's noise mapping. Removed per
maintainer ruling; the parsers already conform.
rules: [enum-invalid-value, enum-case-insensitive]
- name: type
type: enum
values: [buffer, value]
default: buffer
summary: Whether the text names a data container or is a literal value.
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
# -------------------------------------------------------------- flashlight --
- name: flashlight
parent: output
since: "1.20"
summary: >-
The camera flash, usable as a lamp or a stroboscope. Most phones cannot
switch faster than about 25 ms, so high frequencies or duty cycles far from
0.5 may not be reproduced accurately.
children: [input]
attributes: []
agreement: agreed
- name: input
parent: flashlight
since: "1.20"
summary: Drives one parameter of the flashlight.
text: Name of a data container, or a literal number when type is value.
attributes:
- name: parameter
type: enum
required: true
values: [intensity, frequency, dutycycle]
summary: Which parameter of the flashlight this input drives.
value_notes:
intensity: >-
Brightness, from 0 (off) to 1 (maximum). How many levels a phone
supports varies and older models may only manage on and off.
Defaults to 1.
frequency: >-
Strobe frequency. At 0 the light stays on constantly. Defaults to 0.
dutycycle: >-
Fraction of each strobe period the light is on, from 0 (always off)
to 1 (always on). Defaults to 0.5.
agreement: agreed
- name: type
type: enum
values: [buffer, value]
default: buffer
summary: Whether the text names a data container or is a literal value.
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
# -------------------------------------------------------------- bluetooth --
- name: bluetooth
parent: output
since: "1.7"
summary: >-
A Bluetooth Low Energy device written to. Distinct from the bluetooth
element of the input block, which reads from one.
children: [input, config]
attributes:
- name: id
group: matching
type: string
translatable: true
summary: >-
Names the device for the user during scanning, and groups entries:
bluetooth elements sharing an id describe one physical device, across
input and output blocks alike - resolved once, connected once, with
every block working over that one connection. A block without an id is
its own device even if it names the same one.
agreement: agreed
- name: name
group: matching
type: string
summary: Connect only to a device whose name contains this text.
agreement: agreed
- name: nameRegex
group: matching
since: "1.21"
type: regex
summary: >-
Connect only to a device whose whole name matches this regular
expression. Same semantics as on the bluetooth input element.
agreement: agreed
rules: [ble-name-regex]
- name: uuid
group: matching
type: string
summary: Connect only to a device advertising this service UUID.
agreement: agreed
- name: autoConnect
group: matching
type: boolean
default: false
summary: Connect to the first match without showing a scan dialog.
agreement: agreed
- name: address
group: matching
type: string
summary: >-
Connect only to the device with this hardware address. **Using this
attribute makes the experiment Android-only**, exactly as in the input
block.
agreement: platform
platforms: [android]
- name: mtu
group: matching
type: integer
default: 0
since: "1.9"
summary: Requests a specific MTU. Fails on Android before 5.0.
agreement: platform
platforms: [android]
remark: >-
iOS gives no control over the MTU and always requests the maximum, so
the attribute is accepted and ignored there.
note: >-
iOS has no way to control the MTU and always requests the maximum.
- name: input
parent: bluetooth
since: "1.7"
summary: >-
Writes the values of a data container to a characteristic, converting them
to bytes.
text: Name of the data container.
attributes:
- name: char
type: string
required: true
summary: UUID of the characteristic to write.
agreement: agreed
- name: conversion
type: enum
values:
- uInt8
- int8
- uInt16LittleEndian
- uInt16BigEndian
- int16LittleEndian
- int16BigEndian
- uInt24LittleEndian
- uInt24BigEndian
- int24LittleEndian
- int24BigEndian
- uInt32LittleEndian
- uInt32BigEndian
- int32LittleEndian
- int32BigEndian
- float32LittleEndian
- float32BigEndian
- float64LittleEndian
- float64BigEndian
- singleByte
- string
- byteArray
required: true
summary: >-
Name of the conversion turning numbers into bytes. See the conversion
vocabulary at the end of this file.
note: >-
The values inline the output list of the conversions section below
(kept in step by a build check).
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
- name: offset
type: integer
default: 0
summary: Byte offset within the characteristic to write at.
agreement: agreed
- name: keep
type: boolean
default: true
since: "1.19"
summary: >-
Whether the data container keeps its contents after being written.
False clears it, so each value is sent once.
remark: >-
Clearing here only empties the container. It does not restore the
container's init values; only the user's clear-data action does that.
agreement: agreed
- name: triggerId
type: string
since: "1.20"
summary: >-
Send this characteristic's data only when a button whose trigger tag
carries the same id has been pressed, rather than after every
analysis pass. Other inputs of the same device keep sending
periodically.
agreement: agreed
- name: config
parent: bluetooth
since: "1.7"
summary: >-
A constant written to a characteristic once after connecting, typically to
enable a sensor or set an acquisition rate.
text: The value to write, interpreted by the conversion.
attributes:
- name: char
type: string
required: true
summary: UUID of the characteristic to write.
agreement: agreed
- name: conversion
type: enum
values:
- uInt8
- int8
- uInt16LittleEndian
- uInt16BigEndian
- int16LittleEndian
- int16BigEndian
- uInt24LittleEndian
- uInt24BigEndian
- int24LittleEndian
- int24BigEndian
- uInt32LittleEndian
- uInt32BigEndian
- int32LittleEndian
- int32BigEndian
- float32LittleEndian
- float32BigEndian
- float64LittleEndian
- float64BigEndian
- singleByte
- string
- hexadecimal
required: true
summary: Conversion turning the element's text into bytes.
note: >-
The values inline the config list of the conversions section below
(kept in step by a build check).
agreement: agreed
rules: [enum-invalid-value, enum-case-insensitive]
# The conversion vocabulary, shared by the bluetooth elements of both blocks.
#
# Worth recording how this was established, because the obvious method fails.
# Android resolves a conversion by REFLECTION: it looks for a declared class of
# that name taking an XmlPullParser - which then reads its own attributes - and
# falls back to a declared static method of the same name. So the vocabulary is
# the set of declared classes and methods of ConversionsInput/Output/Config, and
# an attribute like decimalPoint appears nowhere in the block parser at all.
# iOS uses a ConversionFunction enum plus a switch for the three names that are
# not simple numeric conversions.
#
# Compared name by name, all three vocabularies agree exactly.
conversions:
numeric: &numeric
- uInt8
- int8
- uInt16LittleEndian
- uInt16BigEndian
- int16LittleEndian
- int16BigEndian
- uInt24LittleEndian
- uInt24BigEndian
- int24LittleEndian
- int24BigEndian
- uInt32LittleEndian
- uInt32BigEndian
- int32LittleEndian
- int32BigEndian
- float32LittleEndian
- float32BigEndian
- float64LittleEndian
- float64BigEndian
input:
summary: Bytes from a characteristic to numbers, for a bluetooth input.
agreement: agreed
functions: *numeric
extra:
- name: singleByte
summary: Synonym for uInt8.
- name: string
summary: >-
Parses the bytes as text. Takes decimalPoint, offset, repeating and
length.
- name: formattedString
summary: >-
Parses the bytes as text and selects one field. Takes separator, label
and index.
output:
summary: Numbers to bytes, for a bluetooth output.
agreement: agreed
functions: *numeric
extra:
- name: singleByte
summary: Synonym for uInt8.
- name: string
summary: Formats the value as text.
- name: byteArray
summary: Writes the buffer contents as raw bytes.
config:
summary: The text of a config element to bytes.
agreement: agreed
functions: *numeric
extra:
- name: singleByte
summary: Synonym for uInt8.
- name: string
summary: Writes the text as-is.
- name: hexadecimal
summary: >-
Parses the text as hexadecimal byte pairs. Spaces are stripped first,
any other non-hexadecimal character makes the result empty, and a
dangling digit of an odd-length text is ignored.