The binary project file is Alternatives/NNN/ProjectData. This page and the
next are drawn from the byte-level notes of
LogicProFormatWriter, tested
by opening generated files in Logic 11.2.2 and 12.0.1, and describing a study of real
sessions. The notes warn that a future Logic release could change the format. All integers
are little-endian.
Root header
| Offset | Size | Value | Meaning |
|---|---|---|---|
0x00 | 4 | 23 47 C0 AB | Magic |
0x04 | 2 | varies | Version code, such as CF 09 (see below) |
0x06 | 10 | 03 00 04 00 00 00 01 00 08 00 | Stable in the study |
0x10 | 4 | File size minus 24 | |
0x14 | 4 | 0 | |
0x18 | The records, to the end of the file |
Version codes cd09, ce09 and cf09 belong to the
Logic 11 generation of files; the source’s notes tie cf09 to Logic 12 in
one place and Logic 11 in another. Twelve different codes were met in the corpus.
Records
After the root header, the file is a flat run of records with no index and no absolute
offsets. A reader takes a record’s size from its header and moves on. The first record is
always gnoS, the song root.
| Offset | Size | Name | Meaning |
|---|---|---|---|
0x00 | 4 | Tag | Four ASCII characters, reversed |
0x04 | 2 | schemaVersion | Schema number of this tag; constant within a file |
0x06 | 2 | classId | Stable per tag, except on qeSM and qSvE, where it is a sequence role |
0x08 | 4 | idx | Object index. Low 16 bits are 0, except on gnoS, where the whole field is 0xFFFFFFFF. Per-track records use trackIndex << 18. |
0x0C | 4 | ordinal | On OCuA and UCuA, ordinal shifted left 16; 0xFFFF on gnoS and vEuA |
0x10 | 2 | link0 | 0 on OCuA, UCuA, gRuA and qSvE; otherwise 0xFFFF |
0x12 | 2 | link1 | On UCuA, a small sub-kind |
0x14 | 2 | link2 | On karT, 0x7FFF or 0 |
0x16 | 2 | 0x0002 in every record | |
0x18 | 2 | 0 in every record | |
0x1A | 1 | headerForm | Same in every record of a file: 2 for root versions cd09, ce09 and cf09, otherwise 1 |
0x1B | 1 | Not described | |
0x1C | 4 | payloadSize | Bytes after the header. Total record size is 0x24 + payloadSize. |
0x20 | 4 | 0 in every record | |
0x24 | Payload |
Sequence roles
On qeSM and qSvE, classId at offset
0x06 says what the sequence holds.
| Value | Sequence |
|---|---|
| 1 | Time signature |
| 3 | Tempo |
0x0E, 0x19 | Empty |
0x16 | Markers |
0x17 | Note events |
A qSvE is a run of events and a 16-byte tail: F1 00 00 00 FF FF FF
3F and eight zero bytes. See events
and regions.
Time
Logic’s time is 960 ticks per quarter note, so one bar of 4/4 is 3840 ticks. Positions are stored with an origin added:
| Used for | Origin | Why |
|---|---|---|
| Regions, MIDI and audio | 34,560 | Nine bars of 4/4 |
| Tempo events, markers and notes | 38,400 | 34,560 plus one bar |
Sample rate
The project rate is set in the gnoS payload, not in
MetaData.plist.
| Payload offset | Size | 44.1 kHz | 48 kHz |
|---|---|---|---|
+0xDF | 1 | 0x00 | 0x16 |
+0x11E | 2 | 0xE970 | 0xF8AC |
+0x120 | 2 | 0xE970 | 0xF8AC |
The study confirms only these two rates. It also notes that the byte at
+0xDF is not itself the rate.
Not confirmed
- Many other fields, which the study itself marks open or low-confidence, including the
flag words in
gRuA, and fields ofgnoSandOCuA. - Automation lanes, region gain, and variable-length sysex events.
- Files older than Logic 11, which the study covers less fully.