diff --git a/README.md b/README.md index 5ab49fc62..2957a56ff 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ It was originally designed to query, inspect and debug media codecs and containe [aac_frame](doc/formats.md#aac_frame), adts, adts_frame, +[adm](doc/formats.md#adm), aiff, amf0, apev2, @@ -53,6 +54,7 @@ avc_sei, avc_sps, [avi](doc/formats.md#avi), [avro_ocf](doc/formats.md#avro_ocf), +[axml](doc/formats.md#adm), [bencode](doc/formats.md#bencode), bitcoin_blkdat, [bitcoin_block](doc/formats.md#bitcoin_block), @@ -66,7 +68,9 @@ bsd_loopback_frame, bzip2, [caff](doc/formats.md#caff), [cbor](doc/formats.md#cbor), +[chna](doc/formats.md#adm), [csv](doc/formats.md#csv), +[dolby_metadata](doc/formats.md#dolby_metadata), dns, dns_tcp, elf, diff --git a/doc/formats.md b/doc/formats.md index 80b7aea4b..ab6e3c03e 100644 --- a/doc/formats.md +++ b/doc/formats.md @@ -7,6 +7,7 @@ |[`aac_frame`](#aac_frame) |Advanced Audio Coding frame || |`adts` |Audio Data Transport Stream |`adts_frame`| |`adts_frame` |Audio Data Transport Stream frame |`aac_frame`| +|[`adm`](#adm) |Audio Definition Model |`riff`| |`aiff` |Audio Interchange File Format || |`amf0` |Action Message Format 0 || |`apev2` |APEv2 metadata tag |`image`| @@ -25,6 +26,7 @@ |`avc_sps` |H.264/AVC Sequence Parameter Set || |[`avi`](#avi) |Audio Video Interleaved |`avc_au` `hevc_au` `mp3_frame` `flac_frame`| |[`avro_ocf`](#avro_ocf) |Avro object container file || +|[`axml`](#adm) |Audio Definition Model  Chunk |`riff`| |[`bencode`](#bencode) |BitTorrent bencoding || |`bitcoin_blkdat` |Bitcoin blk.dat |`bitcoin_block`| |[`bitcoin_block`](#bitcoin_block) |Bitcoin block |`bitcoin_transaction`| @@ -38,7 +40,9 @@ |`bzip2` |bzip2 compression |`probe`| |[`caff`](#caff) |Live2D Cubism archive |`probe`| |[`cbor`](#cbor) |Concise Binary Object Representation || +|[`chna`](#adm) |Audio Definition Model  Chunk |`riff`| |[`csv`](#csv) |Comma separated values || +|[`dolby_metadata`](#dolby_metadata) |Dolby Metadata (Atmos, AC3, Digital Plus) |`riff`| |`dns` |DNS packet || |`dns_tcp` |DNS packet (TCP) || |`elf` |Executable and Linkable Format || @@ -179,6 +183,27 @@ Decode value as aac_frame ... | aac_frame({object_type:1}) ``` +## adm +[Audio Definition Model](https://adm.ebu.io/background/what_is_the_adm.html) including 3D Audio. + +RIFF / WAV / Broadcast Wave Format (BWF) chunks: +- `` Chunk, Track UIDs of Audio Definition Model +- `` Chunk, BWF XML Metadata, e.g. for Audio Definition Model ambisonics and elements + +### Examples +Decode ADM configuration from `` and `` chunks: +``` +$ fq -d wav '.chunks[] | select(.id | IN("chna", "axml")) | tovalue' bwf.wav +``` + +### Authors +- [@johnnymarnell](https://johnnymarnell.github.io), original author + +### References +- https://adm.ebu.io/background/what_is_the_adm.html +- https://tech.ebu.ch/publications/tech3285s7 +- https://tech.ebu.ch/publications/tech3285s5 + ## apple_bookmark Apple BookmarkData. @@ -590,6 +615,23 @@ $ fq -d csv -o comma="\t" to_csv file.tsv $ fq -d csv '.[0] as $t | .[1:] | map(with_entries(.key = $t[.key]))' file.csv ``` +## dolby_metadata +Dolby Metadata from `` chunk of RIFF / WAV / Broadcast Wave Format (BWF), +including Dolby Atmos, AC3, Dolby Digital \[Plus\], and Dolby Audio Info (e.g. LUFS, True Peak). + +### Examples +Decode Dolby metadata from `` chunk: +``` +$ fq -d wav '.chunks[] | select(.id | IN("dbmd")) | tovalue' bwf.wav +``` + +### References +- https://tech.ebu.ch/files/live/sites/tech/files/shared/tech/tech3285s6.pdf +- https://github.com/DolbyLaboratories/dbmd-atmos-parser + +### Authors +- [@johnnymarnell](https://johnnymarnell.github.io), original author + ## fit Garmin Flexible and Interoperable Data Transfer. @@ -782,7 +824,6 @@ LevelDB Table. - Zstandard uncompression is not implemented yet. ### Authors - - [@mikez](https://github.com/mikez), original author ### References diff --git a/format/riff/adm.go b/format/riff/adm.go index 21cd0a1e8..399fef0ee 100644 --- a/format/riff/adm.go +++ b/format/riff/adm.go @@ -25,7 +25,6 @@ func chnaDecode(d *decode.D, size int64) { } func axmlDecode(d *decode.D, size int64) { - // fmt.Println("test axml") // TODO(jmarnell): this chunk is all variable xml, so leave as is? d.FieldRawLen("xml", size*8) } diff --git a/format/riff/common.go b/format/riff/common.go index eeffe6222..6915b9f22 100644 --- a/format/riff/common.go +++ b/format/riff/common.go @@ -60,7 +60,7 @@ var chunkIDDescriptions = scalar.StrMapDescription{ "chna": " Chunk, Track UIDs of Audio Definition Model", "axml": " Chunk, BWF XML Metadata, e.g. for Audio Definition Model ambisonics and elements", - "dbmd": "Dolby Metadata", + "dbmd": "Dolby Metadata, e.g. Atmos, AC3, Dolby Digital [Plus]", "ISMP": "SMPTE timecode", "IDIT": "Time and date digitizing commenced", diff --git a/format/riff/dolby.go b/format/riff/dolby.go index af2cb3801..5ec16f95c 100644 --- a/format/riff/dolby.go +++ b/format/riff/dolby.go @@ -54,8 +54,6 @@ func dbmdDecode(d *decode.D, size int64) any { d.FieldRawLen("unknown_segment_raw", int64(segmentSize*8)) } - fmt.Println("bytesRead: ", (bitsLeft-d.BitsLeft())/8, " segment size:", segmentSize) - bytesRemaining := (bitsLeft-d.BitsLeft())/8 - int64(segmentSize) if bytesRemaining < 0 { d.Fatalf("Read too many bytes for segment %d, read %d over, expected %d", segmentID, -bytesRemaining, segmentSize) @@ -63,6 +61,7 @@ func dbmdDecode(d *decode.D, size int64) any { d.FieldValueUint("SKIPPED_BYTES", uint64(bytesRemaining)) d.SeekRel((int64(segmentSize) - bytesRemaining) * 8) } + d.FieldU8("metadata_segment_checksum") }) } @@ -227,7 +226,6 @@ func parseAudioInfo(d *decode.D) { func parseDolbyAtmos(d *decode.D, size uint64) { d.FieldValueStr("metadata_segment_type", "dolby_atmos") - bitsLeft := d.BitsLeft() // d.SeekRel(32 * 8) str := d.FieldUTF8Null("atmos_dbmd_content_creation_preamble") @@ -248,14 +246,10 @@ func parseDolbyAtmos(d *decode.D, size uint64) { d.SeekRel(15 * 8) d.SeekRel(80 * 8) - - fmt.Println("test", int64(size)*8-(bitsLeft-d.BitsLeft())) - d.SeekRel(int64(size)*8 - (bitsLeft - d.BitsLeft())) } func parseDolbyAtmosSupplemental(d *decode.D, size uint64) { d.FieldValueStr("metadata_segment_type", "dolby_atmos_supplemental") - bitsLeft := d.BitsLeft() sync := d.FieldU32LE("dasms_sync") d.FieldValueBool("dasms_sync_valid", sync == 0xf8726fbd) @@ -281,8 +275,8 @@ func parseDolbyAtmosSupplemental(d *decode.D, size uint64) { nonZeroBytes = append(nonZeroBytes, fmt.Sprintf("%d", b)) } } - // TODO(jmarnell): I think the +3dB trim settings are here. Would like this as an array of numbers - // at least, instead of CSV string + // TODO(jmarnell): I think the +3dB trim settings are here. + // Would like this at least as an array of numbers, instead of this CSV string d.FieldValueStr("trim_defs", strings.Join(nonZeroBytes, ", ")) i++ @@ -297,7 +291,4 @@ func parseDolbyAtmosSupplemental(d *decode.D, size uint64) { d.FieldValueUint("render_mode", mode) d.FieldValueStr("render_mode_type", binaural[mode]) }) - - fmt.Println("test", int64(size)*8-(bitsLeft-d.BitsLeft())) - d.SeekRel(int64(size)*8 - (bitsLeft - d.BitsLeft())) }