Commit 9e27ee11 authored by Mans Rullgard's avatar Mans Rullgard

document bitstream format

parent 7bdb3451
====================
MQA bitstream format
====================
The primary MQA bitstream is formed by the XOR of one bit from each
left/right sample pair. The position of this bit within the 24-bit
samples is in the range 8-15 inclusive.
This document describes the format of the MQA bitstream. All fields are
read least significant bit first. Where possible, names are aligned
with text strings found within the decoder binary.
Packet structure
~~~~~~~~~~~~~~~~
The MQA bitstream is structured as a sequence of packets. Each packet
begins with a 4-bit type identifier and ends with a 4-bit checksum.
The size and interpretation of the intervening payload depends on the
packet type. ::
mqa_stream() {
for (;;) {
mqa_packet()
}
}
mqa_packet() {
packet_type uint(4)
if (packet_type == 0) {
hole()
} else if (packet_type == 1) {
reconstruction()
} else if (packet_type == 2) {
data()
} else if (packet_type == 3) {
terminate()
} else if (packet_type == 4) {
authentication()
} else if (packet_type == 5) {
datasync()
} else if (packet_type == 5) {
packet_6()
} else if (packet_type == 7) {
metadata()
} else if (packet_type == 8) {
key()
}
checksum uint(4)
}
`packet_type`
===== ==============
Value Type
===== ==============
0 hole
1 reconstruction
2 data
3 terminate
4 authentication
5 datasync
6 packet_6
7 metadata
8 key
===== ==============
`checksum`
CRC computed over the `packet_type` field and the payload.
Packet types
~~~~~~~~~~~~
Hole
----
Hole packets serve as padding in the bitstream. The payload is ignored
apart from the checksum calculation. ::
hole() {
size uint(4)
if (size == 15) {
size uint(12)
}
junk bits(size)
}
`size`
Number of following bits to skip.
`junk`
Ignored.
Reconstruction
--------------
Reconstruction packets carry touchup data for the audio base band. ::
reconstruction() {
size uint(12)
data bits(size)
}
`size`
Number of following data bits.
`data`
Touchup data.
Data
----
The purpose of this packet type is unknown. ::
data() {
unknown uint(8)
size uint(12)
data bits(size)
}
`size`
Number of following data bits.
`data`
Data bits.
Terminate
---------
Terminate packets indicate the end position of an MQA stream. ::
terminate() {
bits_to_end uint(17)
}
`bits_to_end`
Number of bits in stream following this packet.
Authentication
--------------
These packets carry encrypted data for authentication of the audio
stream. ::
authentication() {
auth_level uint(4)
auth_data bits(3072)
}
`auth_level`
Authentication level provided. Matches the field with the same name
in the `datasync` packet. Also specifies decryption key.
`auth_data`
Encrypted authentication data.
Authentication data
"""""""""""""""""""
The authentication data is decrypted using the RSA algorithm with a
separate key for each `auth_level` value. It is then further
descrambled using the BLAKE2s hash function. The format of the thus
decrypted data is detailed below. ::
auth_data() {
unknown bits(63)
auth_lsb uint(1)
unknown bits(24)
auth_info bits(4)
auth_level uint(4)
stage2_crc uint(32)
stage1_hash bits(256)
lsb_hash[0] bits(256)
lsb_hash[1] bits(256)
lsb_hash[2] bits(256)
lsb_hash[3] bits(256)
lsb_hash[4] bits(256)
lsb_hash[5] bits(256)
lsb_hash[6] bits(256)
lsb_hash[7] bits(256)
lsb_hash[8] bits(256)
unknown bits(32)
pad bits(96)
auth_hash bits(256)
}
`auth_lsb`
1 if low 8 bits are authenticated.
`auth_info`
Matches field with same name in `datasync` packet.
`auth_level`
Matches field with same name in `datasync` packet.
`stage2_crc`
CRC-32 of audio data after stage 2 decoding.
`stage1_hash`
BLAKE2s hash of top 16 bits of audio data after stage 1 decoding.
`lsb_hash`
BLAKE2s hash of the low 8 bits of the input stream. Any of the 9
provided hashes may match.
`auth_hash`
BLAKE2s hash of the preceding `auth_data` bits.
Datasync
--------
This packet type identifies the stream as MQA and provides basic
information for the decoder. ::
datasync() {
magic uint(36)
stream_pos_flag uint(1)
unused bits(1)
orig_rate uint(5)
src_rate uint(5)
render_filter uint(5)
unknown uint(5)
unknown uint(1)
unknown uint(1)
unused bits(1)
auth_info uint(4)
auth_level uint(4)
item_count uint(7)
for (i = 0; i < item_count; i++) {
size[i] uint(8)
}
for (i = 0; i < item_count; i++) {
type[i] uint(8)
}
if (stream_pos_flag) {
stream_position uint(32)
}
for (i = 0; i < item_count; i++) {
if (type[i] == 0) {
ds_item_0()
} else if (type[i] == 1) {
ds_item_1()
} else if (type[i] == 2) {
ds_item_2()
} else if (type[i] == 3) {
cipher_data()
}
}
}
`magic`
The 36-bit value 0x11319207d.
`stream_pos_flag`
0 if this is the first packet, 1 otherwise.
`orig_rate`
Original sample rate of audio.
`src_rate`
Sample rate of this stream.
`render_filter`
Index of upsampling filter to use in the render stage.
`auth_info`
Unknown meaning. Also present in encrypted `auth_data`.
`auth_level`
Authentication level provided for this stream. Values greater than or
equal to 9 indicate "Studio" or "blue" level. Lower values indicate
"green" level.
`item_count`
Number of additional data items contained in this packet.
`size[i]`
Size in bits of each additional data item.
`type[i]`
Type of each additional data item.
`stream_position`
Indicates the sample position of the first bit of this packet within
the MQA stream. If absent, a value of 0 is implied.
The `orig_rate` and `src_rate` fields are composed of a 2-bit base rate
index (MSBs) and a 3-bit scale factor (LSBs).
===== ==========
Index Rate (kHz)
===== ==========
0 44.1
1 48
2 64
3 invalid
===== ==========
===== ==========
Scale Multiplier
===== ==========
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128
===== ==========
The fixed fields are followed by additional data items according to the
`type` and `size` arrays.
Type 0
""""""
Parameters releated to reconstruction of base band audio. ::
ds_item_0() {
stage2_dither uint(2)
gain_index uint(4)
unknown uint(7)
unknown uint(7)
if (stream_pos_flag) {
start_pos uint(27)
pad bits(1)
data bits(*)
}
}
`stage2_dither`
Indicates whether stage 2 reconstruction uses pseudo-random dither.
`gain_index`
Table index for amount of stage 2 gain.
`start_pos`
Sample position divided by 32 at which data applies.
`data`
Priming values for dither shaping filter.
Type 1
""""""
Parameters related to decoding of data carried in low 8 bits. ::
ds_item_1() {
unknown uint(6)
unknown uint(2)
unknown uint(1)
unknown uint(2)
if (stream_pos_flag) {
unknown uint(8)
unknown uint(1)
offset sint(12)
}
}
Type 2
""""""
Type 2 data items contain a subset of the type 1 fields. ::
ds_item_2() {
unknown uint(6)
unknown uint(2)
if (stream_pos_flag) {
unknown uint(3)
unknown uint(1)
offset sint(12)
}
}
Cipher data
"""""""""""
If this item is present, bits 16-21 of the audio data are descrambled
using the Salsa20 stream cipher. ::
cipher_data() {
cipher_iv uint(64)
start_pos uint(32)
}
`cipher_iv`
64-bit IV for use with the Salsa20 stream cipher.
`start_pos`
Sample position at which `cipher_iv` becomes valid.
Packet 6
--------
Unknown data, ignored by the decoder. ::
packet_6() {
size uint(12)
data bits(size)
}
Metadata
--------
Metadata packets carry information such as track title and artist name
in ID3v2 or some other format. Metadata blocks larger than 256 octets
may be fragmented across multiple MQA packets. ::
metadata() {
metadata_type uint(7)
is_last uint(1)
fragment_number uint(12)
size uint(8)
for (i = 0; i < size + 1; i++) {
data uint(8)
}
}
`metadata_type`
===== =======
Value Format
===== =======
1 ID3v2
2 unknown
===== =======
`is_last`
1 of this is the last fragment, 0 otherwise
`fragment_number`
The fragment number contained in this packet.
`size`
Payload size in octets minus 1.
Key
---
Cryptographic key data, purpose unclear. ::
key() {
size uint(12)
unknown uint(32)
data bits(*)
}
`size`
Number of following bits in packet.
`data`
Key data, 2048 bits expected.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment