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
In either case, _subtype_ is followed by the unexplained two-byte value found in many row types that Mr. Lesniak called __index_shift__, and then by _id_, the ID of this artist row itself, at bytes{nbsp}``04``-`07`, an unknown value at byte{nbsp}``08``, and __ofs_name_near__ at byte{nbsp}``09`` (labeled _o~n~_), the one-byte name offset used only in the first variant.
283
-
284
-
If _subtype_ is `0064`, the value of __ofs_name_near__ is ignored, and instead the two-byte value __ofs_name_far__ (labeled _o~far~_) is used. Which of either
285
-
variants occurs seems to also depend on the length of the name, so the `64 00` subtype may occur even if
286
-
the string itself is placed directly following __ofs_name_far__.
287
-
288
-
Whichever name offset is used, it is a pointer to the artist name.
289
-
To find the location of the name, add the value of the offset to the address of the start of the artist row itself.
290
-
This gives the address of a DeviceSQL string holding the name, with the structure explained in <<devicesql-strings>>.
291
-
292
243
[#album-rows]
293
244
=== Album Rows
294
245
295
246
Album rows hold an album name and ID along with an artist association, with the two structure variants shown below.
296
-
The value at bytes bytes{nbsp}``00``-`01` are the subtype and differentiate the two variants (similar to the album rows). The value `80 00` is for the short version while `84 00` is for the long version.
297
-
It is
298
-
followed by a two-byte value Mr. Lesniak called __index_shift__, although I don’t know what that means, and another four bytes of unknown purpose.
247
+
The value at bytes bytes{nbsp}``00``-`01` are the _subtype_ and differentiate the two variants.footnote:subtype[The Album, Artist, Tag, Tag Track, and Track tables all use subtypes to determine the size of string offsets, although Track rows seem to always be big enough to require the two-byte offset variant.]
248
+
The value `80` is for the short version while `84` is for the long version.
249
+
It is followed by a two-byte value Mr. Lesniak called __index_shift__, although I don’t know what that means, and another four bytes of unknown purpose.
299
250
But at bytes{nbsp}``08``-`0b` we finally find a value we have a use for: __artist_id__ holds the ID of an artist row associated with this track row.
300
251
This is followed by __id__, the ID of this track row itself, at bytes{nbsp}``0c``-`0f`.
301
252
We assume that there are index tables somewhere that would let us locate the page and row index of a record given its table type and ID, but we have not yet found and figured them out.
302
253
254
+
This is followed by four more bytes with unknown meaning, and then the two subtypes diverge, because the remaining values consume a different number of bytes in each variant:
255
+
256
+
For subtype `80` there is a byte holding the value `03` followed by the final byte in the row, __ofs_name_near__ at byte{nbsp}``15``, a single byte pointer to the track name (labeled _o~n~_ in the <<album-row-near,byte field diagram>>). To find the location of the name, add __ofs_name_near__ bytes to the address of the start of the track row.
257
+
258
+
If the subtype is `84`, the row is of the second form, so the value `0003` takes up two bytes, followed by a two byte offset, __ofs_name_far__, at bytes{nbsp}``16``–`17` (labeled _o~far~_ in the <<album-row-far,diagram>>).
259
+
260
+
Which variant occurs seems to also depend on the length of the name (if the string takes more than about 200 bytes, the far name variant is used), so the `84` subtype may occur even if the string itself is placed directly following __ofs_name_far__.
303
261
304
-
This is followed by five more bytes with unknown meaning, and for subtype `80 00` the final byte in the row, __ofs_name_near__ is a pointer to the track name (labeled _o~n~_ in the byte field diagram).
305
-
To find the location of the name, add __ofs_name_near__ bytes to the address of the start of the
306
-
track row. If the subtype is `84 00`, the row is of the second form, with an additinal two byte offset __ofs_name_far__. In this case, the __ofs_name_near__ is ignored (though usually `00`). Which of either
307
-
variants occurs seems to also depend on the length of the name, so the `84 00` subtype may occur even if
308
-
the string itself is placed directly following __ofs_name_far__.
309
262
The name itself is encoded in a surprisingly baroque way, explained in <<devicesql-strings>>.
310
263
311
264
[#album-row-near]
@@ -319,7 +272,7 @@ The name itself is encoded in a surprisingly baroque way, explained in <<devices
Artist rows hold an Artist name and ID, with the structure shown in <<artist-row-near>> or
299
+
<<artist-row-far>>.
300
+
The _subtype_ value at bytes{nbsp}``00``-`01` determines which variant is used.footnote:subtype[]
301
+
If the artist name is short enough and was allocated close enough to the row to be reached by a single
302
+
byte offset, _subtype_ has the value `0060`, and the row has the structure in <<artist-row-near>>
303
+
If the name is larger than about 200 bytes or is too far away for that, _subtype_ has the value `0064` and the row has the structure in <<artist-row-far>>
In either case, _subtype_ is followed by the unexplained two-byte value found in many row types that Mr. Lesniak called __index_shift__, and then by _id_, the ID of this artist row itself, at bytes{nbsp}``04``-`07`.
334
+
After the id, the number 3 is always stored, followed by the offset to the name string.
335
+
For subtype `0060`, each of these values take a single byte, and __ofs_name_near__ at byte{nbsp}``09`` (labeled _o~n~_), is the one-byte name offset.
336
+
For subtype `0064`, each is stored in two bytes, and the two-byte name offset value __ofs_name_far__ (labeled _o~far~_) is found at bytes{nbsp}``0a``–`0b`.
337
+
338
+
Whichever name offset is used, it is a pointer to the artist name.
339
+
To find the location of the name, add the value of the offset to the address of the start of the artist row itself.
340
+
This gives the address of a DeviceSQL string holding the name, with the structure explained in <<devicesql-strings>>.
341
+
342
+
342
343
[#artwork-rows]
343
344
=== Artwork Rows
344
345
@@ -538,28 +539,50 @@ Tags provide a flexible way for DJs to categorize tracks, supported by the “My
538
539
Tags have names, and can be assigned to any number of tracks.
539
540
Tags themselves can be grouped into categories, which are stored in the same table.
540
541
541
-
The rows have the following structure:
542
+
Tag rows have the structure shown in <<tag-row-near>> or
543
+
<<tag-row-far>>.
544
+
The _subtype_ value at bytes{nbsp}``00``-`01` determines which variant is used.footnote:subtype[]
545
+
If the tag name is short enough and was allocated close enough to the row to be reached by a single
546
+
byte offset, _subtype_ has the value `0680`, and the row has the structure in <<tag-row-near>>
547
+
If the name is larger than about 200 bytes or is too far away for that, _subtype_ has the value `0684` and the row has the structure in <<tag-row-far>>
__tag_index__ at bytes{nbsp}``02``–`03` seems to increment by `20` for each row.
563
586
This is followed by another eight bytes of unknown purpose that always seem to be zero.
564
587
565
588
The __category__ at bytes{nbsp}``0c``–``0f`` holds the ID of the category to which the tag belongs; if this row is itself a category, this field has the value 0.
@@ -572,7 +595,17 @@ Tags seem to have very large _id_ values, while the four categories have fixed `
572
595
The value of __raw_is_category__ at bytes{nbsp}``18``–``1b`` is non-zero when this row stores a tag category instead of a tag.
573
596
It is followed by two bytes of unknown purpose that always seem to have the same values, and a byte that may hold some sort of flags that have not yet been understood.
574
597
575
-
A variable number of bytes starting at byte{nbsp}``1f`` is a <<devicesql-strings,DeviceSQL string>> holding the _name_ of the tag or category. Finally, this is followed by a byte with an unknown purpose, whose value always seems to be 3.
598
+
After the __raw_is_category__, the number 3 is always stored, followed by the offset to the name string, and another string offset with unknown purpose.
599
+
600
+
For subtype `0680`, each of these values take a single byte, and __ofs_name_near__ at byte{nbsp}``1d`` (labeled _o~n~_), is the one-byte name offset.
601
+
__ofs_unknown_near__ at byte{nbsp}``1e`` (labeled _o~u~_), is a one-byte offset to what seems to always be an empty string.
602
+
603
+
For subtype `0684`, each is stored in two bytes, and the two-byte name offset value __ofs_name_far__ (labeled _o~far~_) is found at bytes{nbsp}``1e``–`1f`.
604
+
The offset to the unknown (but seemingly always empty) string (labeled _o~ufar~_) takes the final two bytes.
605
+
606
+
Whichever name offset is used, it is a pointer to the tag name.
607
+
To find the location of the name, add the value of the offset to the address of the start of the tag row itself.
608
+
This gives the address of a DeviceSQL string holding the name, with the structure explained in <<devicesql-strings>>.
0 commit comments