@ac-kit/format-osc 0.0.0-stage → 0.1.1
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.
- package/CHANGELOG.md +40 -0
- package/LICENSE +28 -0
- package/README.md +132 -2
- package/dist/errors.d.ts +34 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/framing/_decode-framed-packet.d.ts +9 -0
- package/dist/framing/_decode-framed-packet.d.ts.map +1 -0
- package/dist/framing/_decode-framed-packet.js +23 -0
- package/dist/framing/_decode-framed-packet.js.map +1 -0
- package/dist/framing/osc-datagram-codec.d.ts +17 -0
- package/dist/framing/osc-datagram-codec.d.ts.map +1 -0
- package/dist/framing/osc-datagram-codec.js +21 -0
- package/dist/framing/osc-datagram-codec.js.map +1 -0
- package/dist/framing/osc-datagram-decoder.d.ts +22 -0
- package/dist/framing/osc-datagram-decoder.d.ts.map +1 -0
- package/dist/framing/osc-datagram-decoder.js +26 -0
- package/dist/framing/osc-datagram-decoder.js.map +1 -0
- package/dist/framing/osc-datagram-encoder.d.ts +8 -0
- package/dist/framing/osc-datagram-encoder.d.ts.map +1 -0
- package/dist/framing/osc-datagram-encoder.js +9 -0
- package/dist/framing/osc-datagram-encoder.js.map +1 -0
- package/dist/framing/osc-size-prefixed-codec.d.ts +19 -0
- package/dist/framing/osc-size-prefixed-codec.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-codec.js +23 -0
- package/dist/framing/osc-size-prefixed-codec.js.map +1 -0
- package/dist/framing/osc-size-prefixed-decoder.d.ts +40 -0
- package/dist/framing/osc-size-prefixed-decoder.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-decoder.js +59 -0
- package/dist/framing/osc-size-prefixed-decoder.js.map +1 -0
- package/dist/framing/osc-size-prefixed-encoder.d.ts +10 -0
- package/dist/framing/osc-size-prefixed-encoder.d.ts.map +1 -0
- package/dist/framing/osc-size-prefixed-encoder.js +20 -0
- package/dist/framing/osc-size-prefixed-encoder.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/packet/_bundle-marker.d.ts +3 -0
- package/dist/packet/_bundle-marker.d.ts.map +1 -0
- package/dist/packet/_bundle-marker.js +3 -0
- package/dist/packet/_bundle-marker.js.map +1 -0
- package/dist/packet/_osc-writer.d.ts +31 -0
- package/dist/packet/_osc-writer.d.ts.map +1 -0
- package/dist/packet/_osc-writer.js +72 -0
- package/dist/packet/_osc-writer.js.map +1 -0
- package/dist/packet/_read-osc-packet.d.ts +19 -0
- package/dist/packet/_read-osc-packet.d.ts.map +1 -0
- package/dist/packet/_read-osc-packet.js +290 -0
- package/dist/packet/_read-osc-packet.js.map +1 -0
- package/dist/packet/_write-osc-packet.d.ts +12 -0
- package/dist/packet/_write-osc-packet.d.ts.map +1 -0
- package/dist/packet/_write-osc-packet.js +155 -0
- package/dist/packet/_write-osc-packet.js.map +1 -0
- package/dist/packet/decode-osc-packet.d.ts +48 -0
- package/dist/packet/decode-osc-packet.d.ts.map +1 -0
- package/dist/packet/decode-osc-packet.js +39 -0
- package/dist/packet/decode-osc-packet.js.map +1 -0
- package/dist/packet/encode-osc-packet.d.ts +32 -0
- package/dist/packet/encode-osc-packet.d.ts.map +1 -0
- package/dist/packet/encode-osc-packet.js +37 -0
- package/dist/packet/encode-osc-packet.js.map +1 -0
- package/dist/packet/osc-packet.d.ts +104 -0
- package/dist/packet/osc-packet.d.ts.map +1 -0
- package/dist/packet/osc-packet.js +2 -0
- package/dist/packet/osc-packet.js.map +1 -0
- package/dist/time-tag/_ntp.d.ts +13 -0
- package/dist/time-tag/_ntp.d.ts.map +1 -0
- package/dist/time-tag/_ntp.js +19 -0
- package/dist/time-tag/_ntp.js.map +1 -0
- package/dist/time-tag/osc-time-tag-from-date.d.ts +29 -0
- package/dist/time-tag/osc-time-tag-from-date.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag-from-date.js +48 -0
- package/dist/time-tag/osc-time-tag-from-date.js.map +1 -0
- package/dist/time-tag/osc-time-tag-to-date.d.ts +21 -0
- package/dist/time-tag/osc-time-tag-to-date.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag-to-date.js +26 -0
- package/dist/time-tag/osc-time-tag-to-date.js.map +1 -0
- package/dist/time-tag/osc-time-tag.d.ts +29 -0
- package/dist/time-tag/osc-time-tag.d.ts.map +1 -0
- package/dist/time-tag/osc-time-tag.js +16 -0
- package/dist/time-tag/osc-time-tag.js.map +1 -0
- package/package.json +60 -3
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { encodeTextUtf8 } from "@ac-kit/core";
|
|
2
|
+
import { assertOscTimeTag_ } from "../time-tag/_ntp.js";
|
|
3
|
+
import { BUNDLE_MARKER_ } from "./_bundle-marker.js";
|
|
4
|
+
const INT32_MIN_ = -2147483648;
|
|
5
|
+
const INT32_MAX_ = 2147483647;
|
|
6
|
+
const INT64_MIN_ = -(2n ** 63n);
|
|
7
|
+
const INT64_MAX_ = 2n ** 63n - 1n;
|
|
8
|
+
const TYPE_TAGS_ = {
|
|
9
|
+
int32: "i",
|
|
10
|
+
float32: "f",
|
|
11
|
+
string: "s",
|
|
12
|
+
blob: "b",
|
|
13
|
+
int64: "h",
|
|
14
|
+
timeTag: "t",
|
|
15
|
+
float64: "d",
|
|
16
|
+
symbol: "S",
|
|
17
|
+
char: "c",
|
|
18
|
+
rgba: "r",
|
|
19
|
+
midi: "m",
|
|
20
|
+
true: "T",
|
|
21
|
+
false: "F",
|
|
22
|
+
nil: "N",
|
|
23
|
+
impulse: "I",
|
|
24
|
+
array: "[",
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Appends `packet` to `writer` — the single implementation of the OSC write
|
|
28
|
+
* grammar, OSC 1.0 §"OSC Packets" through §"OSC Bundles".
|
|
29
|
+
*
|
|
30
|
+
* A type tag string is always written, `,` alone for no arguments, as OSC 1.1
|
|
31
|
+
* requires. Recursion depth is the caller's own nesting; nothing here bounds
|
|
32
|
+
* it.
|
|
33
|
+
*/
|
|
34
|
+
export function writeOscPacket_(writer, packet) {
|
|
35
|
+
if (packet.kind === "message") {
|
|
36
|
+
if (!packet.address.startsWith("/")) {
|
|
37
|
+
throw new RangeError(`encodeOscPacket: address must begin with "/", got ${JSON.stringify(packet.address)}`);
|
|
38
|
+
}
|
|
39
|
+
writer.writePadded(encodeOscString_(packet.address, "address"), 1);
|
|
40
|
+
writer.writePadded(encodeTextUtf8(`,${typeTagsOf_(packet.arguments)}`), 1);
|
|
41
|
+
writeArguments_(writer, packet.arguments);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
assertOscTimeTag_(packet.timeTag, "encodeOscPacket: bundle time tag");
|
|
45
|
+
writer.writePadded(BUNDLE_MARKER_, 0);
|
|
46
|
+
writer.writeUint32(packet.timeTag.seconds);
|
|
47
|
+
writer.writeUint32(packet.timeTag.fraction);
|
|
48
|
+
for (const element of packet.elements) {
|
|
49
|
+
const sizeOffset = writer.allocate(4);
|
|
50
|
+
const start = writer.length;
|
|
51
|
+
writeOscPacket_(writer, element);
|
|
52
|
+
writer.patchUint32(sizeOffset, writer.length - start);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function typeTagsOf_(items) {
|
|
56
|
+
let tags = "";
|
|
57
|
+
for (const item of items) {
|
|
58
|
+
tags += TYPE_TAGS_[item.type];
|
|
59
|
+
if (item.type === "array") {
|
|
60
|
+
tags += `${typeTagsOf_(item.items)}]`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return tags;
|
|
64
|
+
}
|
|
65
|
+
function writeArguments_(writer, items) {
|
|
66
|
+
for (const item of items) {
|
|
67
|
+
switch (item.type) {
|
|
68
|
+
case "int32":
|
|
69
|
+
if (!Number.isInteger(item.value) ||
|
|
70
|
+
item.value < INT32_MIN_ ||
|
|
71
|
+
item.value > INT32_MAX_) {
|
|
72
|
+
throw new RangeError(`encodeOscPacket: int32 must be an integer in -2^31..2^31-1, got ${item.value}`);
|
|
73
|
+
}
|
|
74
|
+
writer.writeUint32(item.value);
|
|
75
|
+
break;
|
|
76
|
+
case "float32":
|
|
77
|
+
writer.writeFloat32(item.value);
|
|
78
|
+
break;
|
|
79
|
+
case "string":
|
|
80
|
+
case "symbol":
|
|
81
|
+
writer.writePadded(encodeOscString_(item.value, item.type), 1);
|
|
82
|
+
break;
|
|
83
|
+
case "blob":
|
|
84
|
+
if (item.value.length > INT32_MAX_) {
|
|
85
|
+
throw new RangeError(`encodeOscPacket: blob of ${item.value.length} bytes exceeds the int32 size field`);
|
|
86
|
+
}
|
|
87
|
+
writer.writeUint32(item.value.length);
|
|
88
|
+
writer.writePadded(item.value, 0);
|
|
89
|
+
break;
|
|
90
|
+
case "int64":
|
|
91
|
+
if (item.value < INT64_MIN_ || item.value > INT64_MAX_) {
|
|
92
|
+
throw new RangeError(`encodeOscPacket: int64 must be in -2^63..2^63-1, got ${item.value}`);
|
|
93
|
+
}
|
|
94
|
+
writer.writeUint64(BigInt.asUintN(64, item.value));
|
|
95
|
+
break;
|
|
96
|
+
case "timeTag":
|
|
97
|
+
assertOscTimeTag_(item.value, "encodeOscPacket: timeTag argument");
|
|
98
|
+
writer.writeUint32(item.value.seconds);
|
|
99
|
+
writer.writeUint32(item.value.fraction);
|
|
100
|
+
break;
|
|
101
|
+
case "float64":
|
|
102
|
+
writer.writeFloat64(item.value);
|
|
103
|
+
break;
|
|
104
|
+
case "char":
|
|
105
|
+
writer.writeUint32(charCodePoint_(item.value));
|
|
106
|
+
break;
|
|
107
|
+
case "rgba":
|
|
108
|
+
writer.writeBytes4(byte_(item.red, "rgba red"), byte_(item.green, "rgba green"), byte_(item.blue, "rgba blue"), byte_(item.alpha, "rgba alpha"));
|
|
109
|
+
break;
|
|
110
|
+
case "midi":
|
|
111
|
+
writer.writeBytes4(byte_(item.port, "midi port"), byte_(item.status, "midi status"), byte_(item.data1, "midi data1"), byte_(item.data2, "midi data2"));
|
|
112
|
+
break;
|
|
113
|
+
case "true":
|
|
114
|
+
case "false":
|
|
115
|
+
case "nil":
|
|
116
|
+
case "impulse":
|
|
117
|
+
break;
|
|
118
|
+
case "array":
|
|
119
|
+
writeArguments_(writer, item.items);
|
|
120
|
+
break;
|
|
121
|
+
default:
|
|
122
|
+
item;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* UTF-8 bytes of an OSC-string. A NUL would end the string early on the wire,
|
|
128
|
+
* and a lone surrogate would be replaced by U+FFFD, so both are refused rather
|
|
129
|
+
* than sent as something else.
|
|
130
|
+
*/
|
|
131
|
+
function encodeOscString_(text, what) {
|
|
132
|
+
if (text.includes("\0")) {
|
|
133
|
+
throw new RangeError(`encodeOscPacket: ${what} contains a NUL character`);
|
|
134
|
+
}
|
|
135
|
+
if (!text.isWellFormed()) {
|
|
136
|
+
throw new RangeError(`encodeOscPacket: ${what} contains a lone surrogate`);
|
|
137
|
+
}
|
|
138
|
+
return encodeTextUtf8(text);
|
|
139
|
+
}
|
|
140
|
+
function charCodePoint_(value) {
|
|
141
|
+
const codePoint = value.codePointAt(0);
|
|
142
|
+
if (codePoint === undefined ||
|
|
143
|
+
value.length !== (codePoint > 0xffff ? 2 : 1) ||
|
|
144
|
+
(codePoint >= 0xd800 && codePoint <= 0xdfff)) {
|
|
145
|
+
throw new RangeError(`encodeOscPacket: char must be exactly one code point, got ${JSON.stringify(value)}`);
|
|
146
|
+
}
|
|
147
|
+
return codePoint;
|
|
148
|
+
}
|
|
149
|
+
function byte_(value, what) {
|
|
150
|
+
if (!Number.isInteger(value) || value < 0 || value > 0xff) {
|
|
151
|
+
throw new RangeError(`encodeOscPacket: ${what} must be an integer in 0..255, got ${value}`);
|
|
152
|
+
}
|
|
153
|
+
return value;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=_write-osc-packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_write-osc-packet.js","sourceRoot":"","sources":["../../src/packet/_write-osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,MAAM,UAAU,GAAG,CAAC,UAAa,CAAC;AAClC,MAAM,UAAU,GAAG,UAAa,CAAC;AACjC,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC;AAChC,MAAM,UAAU,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,CAAC;AAElC,MAAM,UAAU,GAAG;IAClB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,GAAG;IACX,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,GAAG;IACV,GAAG,EAAE,GAAG;IACR,OAAO,EAAE,GAAG;IACZ,KAAK,EAAE,GAAG;CAC6C,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,MAAkB,EAAE,MAAiB;IACpE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,UAAU,CACnB,qDAAqD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CACrF,CAAC;QACH,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1C,OAAO;IACR,CAAC;IAED,iBAAiB,CAAC,MAAM,CAAC,OAAO,EAAE,kCAAkC,CAAC,CAAC;IACtE,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;IACtC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACjC,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IACvD,CAAC;AACF,CAAC;AAED,SAAS,WAAW,CAAC,KAA6B;IACjD,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,IAAI,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QACvC,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,eAAe,CACvB,MAAkB,EAClB,KAA6B;IAE7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,OAAO;gBACX,IACC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;oBAC7B,IAAI,CAAC,KAAK,GAAG,UAAU;oBACvB,IAAI,CAAC,KAAK,GAAG,UAAU,EACtB,CAAC;oBACF,MAAM,IAAI,UAAU,CACnB,mEAAmE,IAAI,CAAC,KAAK,EAAE,CAC/E,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/B,MAAM;YACP,KAAK,SAAS;gBACb,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,MAAM;YACP,KAAK,QAAQ,CAAC;YACd,KAAK,QAAQ;gBACZ,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/D,MAAM;YACP,KAAK,MAAM;gBACV,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC;oBACpC,MAAM,IAAI,UAAU,CACnB,4BAA4B,IAAI,CAAC,KAAK,CAAC,MAAM,qCAAqC,CAClF,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACtC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAClC,MAAM;YACP,KAAK,OAAO;gBACX,IAAI,IAAI,CAAC,KAAK,GAAG,UAAU,IAAI,IAAI,CAAC,KAAK,GAAG,UAAU,EAAE,CAAC;oBACxD,MAAM,IAAI,UAAU,CACnB,wDAAwD,IAAI,CAAC,KAAK,EAAE,CACpE,CAAC;gBACH,CAAC;gBACD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBACnD,MAAM;YACP,KAAK,SAAS;gBACb,iBAAiB,CAAC,IAAI,CAAC,KAAK,EAAE,mCAAmC,CAAC,CAAC;gBACnE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACxC,MAAM;YACP,KAAK,SAAS;gBACb,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,MAAM;YACP,KAAK,MAAM;gBACV,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC/C,MAAM;YACP,KAAK,MAAM;gBACV,MAAM,CAAC,WAAW,CACjB,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,EAC/B,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAC7B,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAC/B,CAAC;gBACF,MAAM;YACP,KAAK,MAAM;gBACV,MAAM,CAAC,WAAW,CACjB,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,aAAa,CAAC,EACjC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,EAC/B,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAC/B,CAAC;gBACF,MAAM;YACP,KAAK,MAAM,CAAC;YACZ,KAAK,OAAO,CAAC;YACb,KAAK,KAAK,CAAC;YACX,KAAK,SAAS;gBACb,MAAM;YACP,KAAK,OAAO;gBACX,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpC,MAAM;YACP;gBACC,IAAoB,CAAC;QACvB,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,IAAY;IACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAAC,oBAAoB,IAAI,2BAA2B,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAAC,oBAAoB,IAAI,4BAA4B,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACvC,IACC,SAAS,KAAK,SAAS;QACvB,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,SAAS,IAAI,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC,EAC3C,CAAC;QACF,MAAM,IAAI,UAAU,CACnB,6DAA6D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACpF,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,KAAK,CAAC,KAAa,EAAE,IAAY;IACzC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;QAC3D,MAAM,IAAI,UAAU,CACnB,oBAAoB,IAAI,sCAAsC,KAAK,EAAE,CACrE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { OscPacket } from "./osc-packet.js";
|
|
2
|
+
/** Options for {@link decodeOscPacket} and the decoders built on it. */
|
|
3
|
+
export type DecodeOscPacketOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* How many bundles and arrays may enclose one another, counted together: a
|
|
6
|
+
* top-level bundle is one level, an array in a message inside it a second. 0
|
|
7
|
+
* refuses every bundle and array. Defaults to 32 — no OSC implementation in
|
|
8
|
+
* use nests more than a few levels, and the bound keeps a hostile packet from
|
|
9
|
+
* exhausting the stack. Recursion depth, and so stack use, grows with it.
|
|
10
|
+
*/
|
|
11
|
+
maxDepth?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Decodes one whole OSC packet: the bytes of a datagram, or the content of a
|
|
15
|
+
* stream frame. For a transport, prefer the codecs, which handle the framing
|
|
16
|
+
* and report malformed packets as decode results.
|
|
17
|
+
*
|
|
18
|
+
* `bytes` must be exactly one packet; nothing after it is ignored. The decoder
|
|
19
|
+
* is strict where OSC is a network boundary:
|
|
20
|
+
*
|
|
21
|
+
* - Strings and blobs must be padded with NUL bytes, and a packet or bundle
|
|
22
|
+
* element must be a multiple of 4 bytes long;
|
|
23
|
+
* - An unknown type tag is an error, since the size of its data is unknowable;
|
|
24
|
+
* - Every bundle element must fit its bundle, and every argument its message;
|
|
25
|
+
* - Strings are decoded as UTF-8 and must be valid. OSC 1.0 specifies ASCII, of
|
|
26
|
+
* which UTF-8 is a superset, and UTF-8 is what OSC 1.1 implementations send.
|
|
27
|
+
* A byte order mark is kept as U+FEFF.
|
|
28
|
+
*
|
|
29
|
+
* A message with no type tag string, which OSC 1.0 asks receivers to tolerate
|
|
30
|
+
* from older senders, decodes with no arguments when nothing follows its
|
|
31
|
+
* address. If bytes do follow, their types cannot be known, and the message is
|
|
32
|
+
* an error rather than silently losing them.
|
|
33
|
+
*
|
|
34
|
+
* Time is O(n) in `bytes.length`. The result copies every blob, so it never
|
|
35
|
+
* aliases `bytes`.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* decodeOscPacket(datagram);
|
|
40
|
+
* // { kind: "message", address: "/oscillator/4/frequency", arguments: [{ type: "float32", value: 440 }] }
|
|
41
|
+
* ```;
|
|
42
|
+
*
|
|
43
|
+
* @throws {OscPacketError} When `bytes` is not a well-formed packet; its
|
|
44
|
+
* `offset` is the byte offset in `bytes` where decoding gave up.
|
|
45
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
46
|
+
*/
|
|
47
|
+
export declare function decodeOscPacket(bytes: Uint8Array, options?: DecodeOscPacketOptions): OscPacket;
|
|
48
|
+
//# sourceMappingURL=decode-osc-packet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/decode-osc-packet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wEAAwE;AACxE,MAAM,MAAM,sBAAsB,GAAG;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,sBAAsB,GAC9B,SAAS,CAEX"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readOscPacket_, resolveMaxDepth_ } from "./_read-osc-packet.js";
|
|
2
|
+
/**
|
|
3
|
+
* Decodes one whole OSC packet: the bytes of a datagram, or the content of a
|
|
4
|
+
* stream frame. For a transport, prefer the codecs, which handle the framing
|
|
5
|
+
* and report malformed packets as decode results.
|
|
6
|
+
*
|
|
7
|
+
* `bytes` must be exactly one packet; nothing after it is ignored. The decoder
|
|
8
|
+
* is strict where OSC is a network boundary:
|
|
9
|
+
*
|
|
10
|
+
* - Strings and blobs must be padded with NUL bytes, and a packet or bundle
|
|
11
|
+
* element must be a multiple of 4 bytes long;
|
|
12
|
+
* - An unknown type tag is an error, since the size of its data is unknowable;
|
|
13
|
+
* - Every bundle element must fit its bundle, and every argument its message;
|
|
14
|
+
* - Strings are decoded as UTF-8 and must be valid. OSC 1.0 specifies ASCII, of
|
|
15
|
+
* which UTF-8 is a superset, and UTF-8 is what OSC 1.1 implementations send.
|
|
16
|
+
* A byte order mark is kept as U+FEFF.
|
|
17
|
+
*
|
|
18
|
+
* A message with no type tag string, which OSC 1.0 asks receivers to tolerate
|
|
19
|
+
* from older senders, decodes with no arguments when nothing follows its
|
|
20
|
+
* address. If bytes do follow, their types cannot be known, and the message is
|
|
21
|
+
* an error rather than silently losing them.
|
|
22
|
+
*
|
|
23
|
+
* Time is O(n) in `bytes.length`. The result copies every blob, so it never
|
|
24
|
+
* aliases `bytes`.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* decodeOscPacket(datagram);
|
|
29
|
+
* // { kind: "message", address: "/oscillator/4/frequency", arguments: [{ type: "float32", value: 440 }] }
|
|
30
|
+
* ```;
|
|
31
|
+
*
|
|
32
|
+
* @throws {OscPacketError} When `bytes` is not a well-formed packet; its
|
|
33
|
+
* `offset` is the byte offset in `bytes` where decoding gave up.
|
|
34
|
+
* @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
|
|
35
|
+
*/
|
|
36
|
+
export function decodeOscPacket(bytes, options) {
|
|
37
|
+
return readOscPacket_(bytes, resolveMaxDepth_(options?.maxDepth));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=decode-osc-packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-osc-packet.js","sourceRoot":"","sources":["../../src/packet/decode-osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAiB,EACjB,OAAgC;IAEhC,OAAO,cAAc,CAAC,KAAK,EAAE,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { OscPacket } from "./osc-packet.js";
|
|
2
|
+
/**
|
|
3
|
+
* Encodes one OSC packet: the bytes of a datagram, or the content of a stream
|
|
4
|
+
* frame. For a transport, prefer the codecs, which add the framing it needs.
|
|
5
|
+
*
|
|
6
|
+
* Every message gets a type tag string — `,` alone when it has no arguments.
|
|
7
|
+
* Strings are written as UTF-8 with their NUL terminator, strings and blobs are
|
|
8
|
+
* padded with NUL bytes to a multiple of 4, and numbers are big-endian. A
|
|
9
|
+
* `float32` argument is rounded to binary32 as `Math.fround` would, so 1.234
|
|
10
|
+
* reads back as 1.2339999675750732.
|
|
11
|
+
*
|
|
12
|
+
* Time and memory are O(n) in the encoded size.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* encodeOscPacket({
|
|
17
|
+
* kind: "message",
|
|
18
|
+
* address: "/oscillator/4/frequency",
|
|
19
|
+
* arguments: [{ type: "float32", value: 440 }],
|
|
20
|
+
* }); // 32 bytes, ending 2c 66 00 00 43 dc 00 00
|
|
21
|
+
* ```;
|
|
22
|
+
*
|
|
23
|
+
* @returns A fresh buffer, a multiple of 4 bytes long.
|
|
24
|
+
* @throws {RangeError} When the packet cannot be written as given: an address
|
|
25
|
+
* not beginning with `/`; a string, symbol or address containing U+0000 or a
|
|
26
|
+
* lone surrogate; an `int32` that is not an integer in −2^31..2^31 − 1; an
|
|
27
|
+
* `int64` outside −2^63..2^63 − 1; a time tag field that is not an unsigned
|
|
28
|
+
* 32-bit integer; a `char` that is not exactly one code point; an `rgba` or
|
|
29
|
+
* `midi` byte that is not an integer in 0–255.
|
|
30
|
+
*/
|
|
31
|
+
export declare function encodeOscPacket(packet: OscPacket): Uint8Array<ArrayBuffer>;
|
|
32
|
+
//# sourceMappingURL=encode-osc-packet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode-osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/encode-osc-packet.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAK1E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { OscWriter_ } from "./_osc-writer.js";
|
|
2
|
+
import { writeOscPacket_ } from "./_write-osc-packet.js";
|
|
3
|
+
/**
|
|
4
|
+
* Encodes one OSC packet: the bytes of a datagram, or the content of a stream
|
|
5
|
+
* frame. For a transport, prefer the codecs, which add the framing it needs.
|
|
6
|
+
*
|
|
7
|
+
* Every message gets a type tag string — `,` alone when it has no arguments.
|
|
8
|
+
* Strings are written as UTF-8 with their NUL terminator, strings and blobs are
|
|
9
|
+
* padded with NUL bytes to a multiple of 4, and numbers are big-endian. A
|
|
10
|
+
* `float32` argument is rounded to binary32 as `Math.fround` would, so 1.234
|
|
11
|
+
* reads back as 1.2339999675750732.
|
|
12
|
+
*
|
|
13
|
+
* Time and memory are O(n) in the encoded size.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* encodeOscPacket({
|
|
18
|
+
* kind: "message",
|
|
19
|
+
* address: "/oscillator/4/frequency",
|
|
20
|
+
* arguments: [{ type: "float32", value: 440 }],
|
|
21
|
+
* }); // 32 bytes, ending 2c 66 00 00 43 dc 00 00
|
|
22
|
+
* ```;
|
|
23
|
+
*
|
|
24
|
+
* @returns A fresh buffer, a multiple of 4 bytes long.
|
|
25
|
+
* @throws {RangeError} When the packet cannot be written as given: an address
|
|
26
|
+
* not beginning with `/`; a string, symbol or address containing U+0000 or a
|
|
27
|
+
* lone surrogate; an `int32` that is not an integer in −2^31..2^31 − 1; an
|
|
28
|
+
* `int64` outside −2^63..2^63 − 1; a time tag field that is not an unsigned
|
|
29
|
+
* 32-bit integer; a `char` that is not exactly one code point; an `rgba` or
|
|
30
|
+
* `midi` byte that is not an integer in 0–255.
|
|
31
|
+
*/
|
|
32
|
+
export function encodeOscPacket(packet) {
|
|
33
|
+
const writer = new OscWriter_();
|
|
34
|
+
writeOscPacket_(writer, packet);
|
|
35
|
+
return writer.finish();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=encode-osc-packet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encode-osc-packet.js","sourceRoot":"","sources":["../../src/packet/encode-osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB;IAChD,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAChC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { OscTimeTag } from "../time-tag/osc-time-tag.js";
|
|
2
|
+
/**
|
|
3
|
+
* One argument of an OSC message, discriminated by `type`. Each variant names
|
|
4
|
+
* the type tag it travels under:
|
|
5
|
+
*
|
|
6
|
+
* - `int32` (`i`) — a signed 32-bit integer, −2^31 to 2^31 − 1.
|
|
7
|
+
* - `float32` (`f`) — an IEEE 754 binary32; a `number` is rounded to it on
|
|
8
|
+
* encode, as `Math.fround` would.
|
|
9
|
+
* - `string` (`s`) — text, sent as UTF-8; never contains U+0000.
|
|
10
|
+
* - `blob` (`b`) — arbitrary bytes.
|
|
11
|
+
* - `int64` (`h`) — a signed 64-bit integer, as a `bigint`.
|
|
12
|
+
* - `timeTag` (`t`) — an NTP time tag.
|
|
13
|
+
* - `float64` (`d`) — an IEEE 754 binary64.
|
|
14
|
+
* - `symbol` (`S`) — text like `string`, for systems that tell symbols apart.
|
|
15
|
+
* - `char` (`c`) — one character, sent as its code point in 32 bits.
|
|
16
|
+
* - `rgba` (`r`) — a 32-bit colour, each channel 0–255.
|
|
17
|
+
* - `midi` (`m`) — a 4-byte MIDI message: port, status and two data bytes, each
|
|
18
|
+
* 0–255.
|
|
19
|
+
* - `true` (`T`), `false` (`F`), `nil` (`N`), `impulse` (`I`) — values carried by
|
|
20
|
+
* the tag alone. `impulse` is OSC 1.1's name for the tag OSC 1.0 calls
|
|
21
|
+
* Infinitum.
|
|
22
|
+
* - `array` (`[` … `]`) — a nested list of arguments.
|
|
23
|
+
*
|
|
24
|
+
* The types beyond `i`, `f`, `s` and `b` are the ones OSC 1.0 lists as
|
|
25
|
+
* non-standard and OSC 1.1 makes standard.
|
|
26
|
+
*/
|
|
27
|
+
export type OscArgument = {
|
|
28
|
+
type: "int32";
|
|
29
|
+
value: number;
|
|
30
|
+
} | {
|
|
31
|
+
type: "float32";
|
|
32
|
+
value: number;
|
|
33
|
+
} | {
|
|
34
|
+
type: "string";
|
|
35
|
+
value: string;
|
|
36
|
+
} | {
|
|
37
|
+
type: "blob";
|
|
38
|
+
value: Uint8Array;
|
|
39
|
+
} | {
|
|
40
|
+
type: "int64";
|
|
41
|
+
value: bigint;
|
|
42
|
+
} | {
|
|
43
|
+
type: "timeTag";
|
|
44
|
+
value: OscTimeTag;
|
|
45
|
+
} | {
|
|
46
|
+
type: "float64";
|
|
47
|
+
value: number;
|
|
48
|
+
} | {
|
|
49
|
+
type: "symbol";
|
|
50
|
+
value: string;
|
|
51
|
+
} | {
|
|
52
|
+
type: "char";
|
|
53
|
+
/** Exactly one Unicode code point; OSC 1.0 calls for ASCII. */
|
|
54
|
+
value: string;
|
|
55
|
+
} | {
|
|
56
|
+
type: "rgba";
|
|
57
|
+
red: number;
|
|
58
|
+
green: number;
|
|
59
|
+
blue: number;
|
|
60
|
+
alpha: number;
|
|
61
|
+
} | {
|
|
62
|
+
type: "midi";
|
|
63
|
+
port: number;
|
|
64
|
+
status: number;
|
|
65
|
+
data1: number;
|
|
66
|
+
data2: number;
|
|
67
|
+
} | {
|
|
68
|
+
type: "true";
|
|
69
|
+
} | {
|
|
70
|
+
type: "false";
|
|
71
|
+
} | {
|
|
72
|
+
type: "nil";
|
|
73
|
+
} | {
|
|
74
|
+
type: "impulse";
|
|
75
|
+
} | {
|
|
76
|
+
type: "array";
|
|
77
|
+
items: OscArgument[];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* An OSC message: an address pattern and the arguments for the methods it
|
|
81
|
+
* matches.
|
|
82
|
+
*/
|
|
83
|
+
export type OscMessage = {
|
|
84
|
+
kind: "message";
|
|
85
|
+
/**
|
|
86
|
+
* The OSC address pattern, beginning with `/`. It may hold the wildcards of
|
|
87
|
+
* OSC address pattern matching; this package carries it as text.
|
|
88
|
+
*/
|
|
89
|
+
address: string;
|
|
90
|
+
arguments: OscArgument[];
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* An OSC bundle: packets to be acted on together, at the instant `timeTag`
|
|
94
|
+
* names.
|
|
95
|
+
*/
|
|
96
|
+
export type OscBundle = {
|
|
97
|
+
kind: "bundle";
|
|
98
|
+
timeTag: OscTimeTag;
|
|
99
|
+
/** Messages and nested bundles, in order. */
|
|
100
|
+
elements: OscPacket[];
|
|
101
|
+
};
|
|
102
|
+
/** The unit of OSC transmission: a message or a bundle. */
|
|
103
|
+
export type OscPacket = OscMessage | OscBundle;
|
|
104
|
+
//# sourceMappingURL=osc-packet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,WAAW,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IACA,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;CACb,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,EAAE,CAAC;CACtB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-packet.js","sourceRoot":"","sources":["../../src/packet/osc-packet.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OscTimeTag } from "./osc-time-tag.js";
|
|
2
|
+
/** 2^32: one NTP era in seconds, and one second in `fraction` units. */
|
|
3
|
+
export declare const TWO_POW_32_ = 4294967296;
|
|
4
|
+
/** 2^31: `seconds` values at or above it are in NTP era 0 (RFC 4330 §3). */
|
|
5
|
+
export declare const TWO_POW_31_ = 2147483648;
|
|
6
|
+
/** Seconds from 1900-01-01T00:00:00Z to the Unix epoch, 1970-01-01T00:00:00Z. */
|
|
7
|
+
export declare const NTP_UNIX_OFFSET_SECONDS_ = 2208988800;
|
|
8
|
+
/**
|
|
9
|
+
* Throws a `RangeError` unless both fields of `tag` are unsigned 32-bit
|
|
10
|
+
* integers. `what` names the value in the message.
|
|
11
|
+
*/
|
|
12
|
+
export declare function assertOscTimeTag_(tag: OscTimeTag, what: string): void;
|
|
13
|
+
//# sourceMappingURL=_ntp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_ntp.d.ts","sourceRoot":"","sources":["../../src/time-tag/_ntp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,wEAAwE;AACxE,eAAO,MAAM,WAAW,aAAgB,CAAC;AAEzC,4EAA4E;AAC5E,eAAO,MAAM,WAAW,aAAgB,CAAC;AAEzC,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,aAAgB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMrE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** 2^32: one NTP era in seconds, and one second in `fraction` units. */
|
|
2
|
+
export const TWO_POW_32_ = 4294967296;
|
|
3
|
+
/** 2^31: `seconds` values at or above it are in NTP era 0 (RFC 4330 §3). */
|
|
4
|
+
export const TWO_POW_31_ = 2147483648;
|
|
5
|
+
/** Seconds from 1900-01-01T00:00:00Z to the Unix epoch, 1970-01-01T00:00:00Z. */
|
|
6
|
+
export const NTP_UNIX_OFFSET_SECONDS_ = 2208988800;
|
|
7
|
+
/**
|
|
8
|
+
* Throws a `RangeError` unless both fields of `tag` are unsigned 32-bit
|
|
9
|
+
* integers. `what` names the value in the message.
|
|
10
|
+
*/
|
|
11
|
+
export function assertOscTimeTag_(tag, what) {
|
|
12
|
+
if (!isUint32_(tag.seconds) || !isUint32_(tag.fraction)) {
|
|
13
|
+
throw new RangeError(`${what}: seconds and fraction must be integers in 0..2^32-1, got ${tag.seconds} and ${tag.fraction}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function isUint32_(value) {
|
|
17
|
+
return Number.isInteger(value) && value >= 0 && value < TWO_POW_32_;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=_ntp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_ntp.js","sourceRoot":"","sources":["../../src/time-tag/_ntp.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,MAAM,CAAC,MAAM,WAAW,GAAG,UAAa,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,UAAa,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAa,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAe,EAAE,IAAY;IAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CACnB,GAAG,IAAI,6DAA6D,GAAG,CAAC,OAAO,QAAQ,GAAG,CAAC,QAAQ,EAAE,CACrG,CAAC;IACH,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC/B,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,WAAW,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { OscTimeTag } from "./osc-time-tag.js";
|
|
2
|
+
/**
|
|
3
|
+
* Converts an instant to the OSC time tag naming it.
|
|
4
|
+
*
|
|
5
|
+
* The 32-bit `seconds` field wraps every 2^32 s (about 136 years), so a tag is
|
|
6
|
+
* read with the RFC 4330 §3 rule: a value with its most significant bit set is
|
|
7
|
+
* in NTP era 0 (from 1900), one with it clear is in era 1 (from
|
|
8
|
+
* 2036-02-07T06:28:16Z). The instants that rule can name, and so the ones this
|
|
9
|
+
* accepts, run from 1968-01-20T03:14:08Z inclusive to 2104-02-26T09:42:24Z
|
|
10
|
+
* exclusive.
|
|
11
|
+
*
|
|
12
|
+
* The fraction is rounded to the nearest 2^-32 s, so a whole number of
|
|
13
|
+
* milliseconds survives {@link oscTimeTagToDate} exactly. A fractional `number`
|
|
14
|
+
* keeps its sub-millisecond part as far as `number` resolves it.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* oscTimeTagFromDate(0); // { seconds: 2208988800, fraction: 0 }
|
|
19
|
+
* oscTimeTagFromDate(new Date("2036-02-07T06:28:16.500Z")); // { seconds: 0, fraction: 2147483648 }
|
|
20
|
+
* ```;
|
|
21
|
+
*
|
|
22
|
+
* @param date - The instant, as a `Date` or as milliseconds since the Unix
|
|
23
|
+
* epoch (`Date.now()`, `performance.timeOrigin + performance.now()`).
|
|
24
|
+
* @returns A fresh time tag. Never {@link OSC_TIME_TAG_IMMEDIATELY}, except for
|
|
25
|
+
* the one instant 2^-32 s after the 2036 rollover, which the two share.
|
|
26
|
+
* @throws {RangeError} When `date` is invalid or outside the range above.
|
|
27
|
+
*/
|
|
28
|
+
export declare function oscTimeTagFromDate(date: Date | number): OscTimeTag;
|
|
29
|
+
//# sourceMappingURL=osc-time-tag-from-date.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-time-tag-from-date.d.ts","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-from-date.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,CA0BlE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { NTP_UNIX_OFFSET_SECONDS_, TWO_POW_31_, TWO_POW_32_ } from "./_ntp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Converts an instant to the OSC time tag naming it.
|
|
4
|
+
*
|
|
5
|
+
* The 32-bit `seconds` field wraps every 2^32 s (about 136 years), so a tag is
|
|
6
|
+
* read with the RFC 4330 §3 rule: a value with its most significant bit set is
|
|
7
|
+
* in NTP era 0 (from 1900), one with it clear is in era 1 (from
|
|
8
|
+
* 2036-02-07T06:28:16Z). The instants that rule can name, and so the ones this
|
|
9
|
+
* accepts, run from 1968-01-20T03:14:08Z inclusive to 2104-02-26T09:42:24Z
|
|
10
|
+
* exclusive.
|
|
11
|
+
*
|
|
12
|
+
* The fraction is rounded to the nearest 2^-32 s, so a whole number of
|
|
13
|
+
* milliseconds survives {@link oscTimeTagToDate} exactly. A fractional `number`
|
|
14
|
+
* keeps its sub-millisecond part as far as `number` resolves it.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* oscTimeTagFromDate(0); // { seconds: 2208988800, fraction: 0 }
|
|
19
|
+
* oscTimeTagFromDate(new Date("2036-02-07T06:28:16.500Z")); // { seconds: 0, fraction: 2147483648 }
|
|
20
|
+
* ```;
|
|
21
|
+
*
|
|
22
|
+
* @param date - The instant, as a `Date` or as milliseconds since the Unix
|
|
23
|
+
* epoch (`Date.now()`, `performance.timeOrigin + performance.now()`).
|
|
24
|
+
* @returns A fresh time tag. Never {@link OSC_TIME_TAG_IMMEDIATELY}, except for
|
|
25
|
+
* the one instant 2^-32 s after the 2036 rollover, which the two share.
|
|
26
|
+
* @throws {RangeError} When `date` is invalid or outside the range above.
|
|
27
|
+
*/
|
|
28
|
+
export function oscTimeTagFromDate(date) {
|
|
29
|
+
const milliseconds = typeof date === "number" ? date : date.getTime();
|
|
30
|
+
if (!Number.isFinite(milliseconds)) {
|
|
31
|
+
throw new RangeError(`oscTimeTagFromDate: invalid date ${String(date)}`);
|
|
32
|
+
}
|
|
33
|
+
let unixSeconds = Math.floor(milliseconds / 1000);
|
|
34
|
+
let fraction = Math.round(((milliseconds - unixSeconds * 1000) * TWO_POW_32_) / 1000);
|
|
35
|
+
if (fraction === TWO_POW_32_) {
|
|
36
|
+
fraction = 0;
|
|
37
|
+
unixSeconds += 1;
|
|
38
|
+
}
|
|
39
|
+
const ntpSeconds = unixSeconds + NTP_UNIX_OFFSET_SECONDS_;
|
|
40
|
+
if (ntpSeconds < TWO_POW_31_ || ntpSeconds >= TWO_POW_32_ + TWO_POW_31_) {
|
|
41
|
+
throw new RangeError(`oscTimeTagFromDate: ${new Date(milliseconds).toISOString()} is outside the range an NTP time tag names (1968-01-20T03:14:08Z to 2104-02-26T09:42:24Z)`);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
seconds: ntpSeconds >= TWO_POW_32_ ? ntpSeconds - TWO_POW_32_ : ntpSeconds,
|
|
45
|
+
fraction,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=osc-time-tag-from-date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-time-tag-from-date.js","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-from-date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG/E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAmB;IACrD,MAAM,YAAY,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,UAAU,CAAC,oCAAoC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClD,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CACxB,CAAC,CAAC,YAAY,GAAG,WAAW,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,IAAI,CAC1D,CAAC;IACF,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC9B,QAAQ,GAAG,CAAC,CAAC;QACb,WAAW,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,GAAG,wBAAwB,CAAC;IAC1D,IAAI,UAAU,GAAG,WAAW,IAAI,UAAU,IAAI,WAAW,GAAG,WAAW,EAAE,CAAC;QACzE,MAAM,IAAI,UAAU,CACnB,uBAAuB,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,4FAA4F,CACvJ,CAAC;IACH,CAAC;IAED,OAAO;QACN,OAAO,EAAE,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,UAAU;QAC1E,QAAQ;KACR,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OscTimeTag } from "./osc-time-tag.js";
|
|
2
|
+
/**
|
|
3
|
+
* Converts an OSC time tag to the instant it names.
|
|
4
|
+
*
|
|
5
|
+
* `seconds` is read with the RFC 4330 §3 era rule {@link oscTimeTagFromDate}
|
|
6
|
+
* documents, so every tag maps to an instant between 1968-01-20T03:14:08Z and
|
|
7
|
+
* 2104-02-26T09:42:24Z. {@link OSC_TIME_TAG_IMMEDIATELY} is not an instant:
|
|
8
|
+
* test for it with {@link isOscTimeTagImmediately} first.
|
|
9
|
+
*
|
|
10
|
+
* A `Date` holds whole milliseconds, so the fraction is rounded to the nearest
|
|
11
|
+
* millisecond (a half rounds up), at most 0.5 ms from the tag.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* oscTimeTagToDate({ seconds: 2208988800, fraction: 0 }).toISOString(); // "1970-01-01T00:00:00.000Z"
|
|
16
|
+
* ```;
|
|
17
|
+
*
|
|
18
|
+
* @throws {RangeError} When a field of `tag` is not an unsigned 32-bit integer.
|
|
19
|
+
*/
|
|
20
|
+
export declare function oscTimeTagToDate(tag: OscTimeTag): Date;
|
|
21
|
+
//# sourceMappingURL=osc-time-tag-to-date.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-time-tag-to-date.d.ts","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-to-date.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAUtD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { assertOscTimeTag_, NTP_UNIX_OFFSET_SECONDS_, TWO_POW_31_, TWO_POW_32_, } from "./_ntp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Converts an OSC time tag to the instant it names.
|
|
4
|
+
*
|
|
5
|
+
* `seconds` is read with the RFC 4330 §3 era rule {@link oscTimeTagFromDate}
|
|
6
|
+
* documents, so every tag maps to an instant between 1968-01-20T03:14:08Z and
|
|
7
|
+
* 2104-02-26T09:42:24Z. {@link OSC_TIME_TAG_IMMEDIATELY} is not an instant:
|
|
8
|
+
* test for it with {@link isOscTimeTagImmediately} first.
|
|
9
|
+
*
|
|
10
|
+
* A `Date` holds whole milliseconds, so the fraction is rounded to the nearest
|
|
11
|
+
* millisecond (a half rounds up), at most 0.5 ms from the tag.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* oscTimeTagToDate({ seconds: 2208988800, fraction: 0 }).toISOString(); // "1970-01-01T00:00:00.000Z"
|
|
16
|
+
* ```;
|
|
17
|
+
*
|
|
18
|
+
* @throws {RangeError} When a field of `tag` is not an unsigned 32-bit integer.
|
|
19
|
+
*/
|
|
20
|
+
export function oscTimeTagToDate(tag) {
|
|
21
|
+
assertOscTimeTag_(tag, "oscTimeTagToDate");
|
|
22
|
+
const ntpSeconds = tag.seconds >= TWO_POW_31_ ? tag.seconds : tag.seconds + TWO_POW_32_;
|
|
23
|
+
return new Date((ntpSeconds - NTP_UNIX_OFFSET_SECONDS_) * 1000 +
|
|
24
|
+
Math.round((tag.fraction * 1000) / TWO_POW_32_));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=osc-time-tag-to-date.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"osc-time-tag-to-date.js","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-to-date.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,wBAAwB,EACxB,WAAW,EACX,WAAW,GACX,MAAM,WAAW,CAAC;AAGnB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAe;IAC/C,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAE3C,MAAM,UAAU,GACf,GAAG,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,WAAW,CAAC;IAEtE,OAAO,IAAI,IAAI,CACd,CAAC,UAAU,GAAG,wBAAwB,CAAC,GAAG,IAAI;QAC7C,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,CAChD,CAAC;AACH,CAAC"}
|