You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: LCS.md
+45-17Lines changed: 45 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,31 +22,30 @@ The header will be followed by one `0x0A` NL character (for a total of 416 bytes
22
22
A `0x02` STX character marks the start of a series of seemingly always NUL bytes, with a variable length. An additional `0x01` SOH character marks the start of the file's metadata fields. As such, it's recommended software implementions simply seek to the first occurance of `0x01` to begin reading.
23
23
24
24
## Metadata Fields
25
-
Following the header, the metadata fields structure is used to store authorship and timestamp information.
25
+
Following the header, the metadata fields structure is used to store authorship and timestamp information. The metadata fields are not keyed, and instead a fixed encoding order is used in order to interpret the value of each metadata field. Unfortunately this means the purpose of each field is static, and new metadata fields may not be easily added. More importantly, metadata fields may not be omitted entirely.
26
26
27
-
Each metadata field starts with a `uint16` value indicating its *character* length (not byte length) encoded as UTF-16 LE, followed by a `uint16` NUL value, and then the encoded metadata field value.
27
+
Each metadata field starts with a `uint32` value indicating its *character* length (not byte length) and then the encoded metadata field value as a `uint16[]`. A metadata field may be "omitted" by encoding a character length value of 0 and including no additional data. This means each empty metadata field will use 4 bytes.
28
28
29
-
The metadata field values are not null terminated and instead continue instantly to the next `uint16` character length value (if any).
29
+
Even though each metadata field seems to be used as a string, the values do not seem to be null terminated and instead continue instantly to the next metadata field structure (if any).
30
+
31
+
| Field | Data Type | Notes |
32
+
| --- | --- | --- |
33
+
| Character Length |`uint32`| May be 0 |
34
+
| Data |`uint16[]`| Typically a non-null terminated (7-bit) ASCII string |
30
35
31
36
### Encoding Example
32
37
The following encodes a value of "HELLO" in 14 bytes.
33
38
34
39
```
35
-
0x05 0x00 // uint16 character length value (5)
36
-
0x00 0x00 // uint16 NUL value
37
-
0x72 0x00 // UTF-16 LE "H"
38
-
0x69 0x00 // ..."E"
39
-
0x76 0x00 // ..."L"
40
-
0x76 0x00 // ..."L"
41
-
0x79 0x00 // ..."O"
40
+
0x05 0x00 0x00 0x00 // uint32 character length value (5)
41
+
0x72 0x00 // "H"
42
+
0x69 0x00 // "E"
43
+
0x76 0x00 // "L"
44
+
0x76 0x00 // "L"
45
+
0x79 0x00 // "O"
42
46
```
43
47
44
-
A metadata field may be "omitted" by encoding a character length value of 0. Keep in mind, the `uint16` NUL value is still required. This means each empty metadata field will use 4 bytes.
45
-
46
-
### Metadata Field Order
47
-
The metadata fields are not keyed, and instead a fixed encoding order is used in order to interpret the value of each metadata field. Unfortunately this means the purpose of each field is static, and the addition of new fields is unsupported and dangerous.
48
-
49
-
#### Encoding Order
48
+
### Encoding Order
50
49
1. File path of the media file, if any
51
50
2. File author
52
51
3. File creation timestamp
@@ -59,4 +58,33 @@ The metadata fields are not keyed, and instead a fixed encoding order is used in
59
58
Empty metadata field values must still be written, otherwise the official Light-O-Rama software will misinterpret the values and potentially attempt to read sequence data as metadata fields.
60
59
61
60
## Sequence Data
62
-
The sequence data appears to be aligned in 40 byte blocks (this may be a result of my configuration), prefixed by a `uint16` value containing the centiseconds (0.01 seconds) value used by the Light-O-Rama [timing grid](http://www.lightorama.com/help/index.html?concept_compressed_sequences.htm).
61
+
The index following the last metadata field begins the compressed sequence data. The sequence data appears to be aligned in 40 byte blocks (this may be a result of my configuration).
62
+
63
+
### Block
64
+
| Field | Data Type | Notes |
65
+
| --- | --- | --- |
66
+
| Sequence Duration |`uint32`|[Centiseconds](http://www.lightorama.com/help/index.html?concept_compressed_sequences.htm) (0.01 seconds) duration of sequence. This value seems to be used only a few times, with a 0 value "appending" to the current block. |
67
+
| Start |`uint32`| Centiseconds start time of the given effect |
68
+
| Stop |`uint32`| Centiseconds stop time of the given effect |
69
+
| Effect || See #Effects |
70
+
||`uint32`| Unknown purpose, always `0x01`|
71
+
||`uint32`| Unknown purpose, always `0x00`|
72
+
| Unit |`uint32`||
73
+
| Channel |`uint32`||
74
+
75
+
## Effects
76
+
### Intensity
77
+
Intensity controls the "brightness" of a given channel using a start and end value. The hardware controller will step between the two values over the duration of the effect. The sequence compression utility seems to use this single effect for fading, constant on, and constant off behaviors by manipulating the start and end intensity values.
78
+
79
+
| Field | Data Type | Value |
80
+
| --- | --- | --- |
81
+
| Id |`uint32`|`0x00`|
82
+
| Start Intensity |`uint32`| Any value between `[0, 100]`|
83
+
| End Intensity |`uint32`| Any value between `[0, 100]`|
84
+
85
+
### Shimmer
86
+
| Field | Data Type | Value |
87
+
| --- | --- | --- |
88
+
| Id |`uint32`|`0x01`|
89
+
| Start Intensity |`uint32`| Any value between `[0, 100]`|
90
+
| End Intensity |`uint32`| Any value between `[0, 100]`|
0 commit comments