Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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),
Expand All @@ -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,
Expand Down
43 changes: 42 additions & 1 deletion doc/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
|[`aac_frame`](#aac_frame) |Advanced&nbsp;Audio&nbsp;Coding&nbsp;frame |<sub></sub>|
|`adts` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream |<sub>`adts_frame`</sub>|
|`adts_frame` |Audio&nbsp;Data&nbsp;Transport&nbsp;Stream&nbsp;frame |<sub>`aac_frame`</sub>|
|[`adm`](#adm) |Audio&nbsp;Definition&nbsp;Model |<sub>`riff`</sub>|
|`aiff` |Audio&nbsp;Interchange&nbsp;File&nbsp;Format |<sub></sub>|
|`amf0` |Action&nbsp;Message&nbsp;Format&nbsp;0 |<sub></sub>|
|`apev2` |APEv2&nbsp;metadata&nbsp;tag |<sub>`image`</sub>|
Expand All @@ -25,6 +26,7 @@
|`avc_sps` |H.264/AVC&nbsp;Sequence&nbsp;Parameter&nbsp;Set |<sub></sub>|
|[`avi`](#avi) |Audio&nbsp;Video&nbsp;Interleaved |<sub>`avc_au` `hevc_au` `mp3_frame` `flac_frame`</sub>|
|[`avro_ocf`](#avro_ocf) |Avro&nbsp;object&nbsp;container&nbsp;file |<sub></sub>|
|[`axml`](#adm) |Audio&nbsp;Definition&nbsp;Model&nbsp;<axml>&nbsp;Chunk |<sub>`riff`</sub>|
|[`bencode`](#bencode) |BitTorrent&nbsp;bencoding |<sub></sub>|
|`bitcoin_blkdat` |Bitcoin&nbsp;blk.dat |<sub>`bitcoin_block`</sub>|
|[`bitcoin_block`](#bitcoin_block) |Bitcoin&nbsp;block |<sub>`bitcoin_transaction`</sub>|
Expand All @@ -38,7 +40,9 @@
|`bzip2` |bzip2&nbsp;compression |<sub>`probe`</sub>|
|[`caff`](#caff) |Live2D&nbsp;Cubism&nbsp;archive |<sub>`probe`</sub>|
|[`cbor`](#cbor) |Concise&nbsp;Binary&nbsp;Object&nbsp;Representation |<sub></sub>|
|[`chna`](#adm) |Audio&nbsp;Definition&nbsp;Model&nbsp;<chna>&nbsp;Chunk |<sub>`riff`</sub>|
|[`csv`](#csv) |Comma&nbsp;separated&nbsp;values |<sub></sub>|
|[`dolby_metadata`](#dolby_metadata) |Dolby&nbsp;Metadata&nbsp;(Atmos,&nbsp;AC3,&nbsp;Digital&nbspPlus) |<sub>`riff`</sub>|
|`dns` |DNS&nbsp;packet |<sub></sub>|
|`dns_tcp` |DNS&nbsp;packet&nbsp;(TCP) |<sub></sub>|
|`elf` |Executable&nbsp;and&nbsp;Linkable&nbsp;Format |<sub></sub>|
Expand Down Expand Up @@ -177,6 +181,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:
- `<chna>` Chunk, Track UIDs of Audio Definition Model
- `<axml>` Chunk, BWF XML Metadata, e.g. for Audio Definition Model ambisonics and elements

### Examples
Decode ADM configuration from `<chna>` and `<axml>` 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.

Expand Down Expand Up @@ -588,6 +613,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 `<dbmd>` 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 `<dbmd>` 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

Copy link
Owner

@wader wader Aug 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this to a doly_metadata.md file in format/tiff, formats.md is autogenerated via make doc. Then also add something like this https://github.com/wader/fq/blob/master/format/msgpack/msgpack.go#L16-L29 and the documentation will also ge available in the cli fq -h dolby_metadata and help(dolby_metadata)

Same for adm above

## fit
Garmin Flexible and Interoperable Data Transfer.

Expand Down Expand Up @@ -780,7 +822,6 @@ LevelDB Table.
- Zstandard uncompression is not implemented yet.

### Authors

- [@mikez](https://github.com/mikez), original author

### References
Expand Down
30 changes: 30 additions & 0 deletions format/riff/adm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package riff

// Audio Definition Model
// https://adm.ebu.io/background/what_is_the_adm.html
// https://tech.ebu.ch/publications/tech3285s7
// https://tech.ebu.ch/publications/tech3285s5

import (
"github.com/wader/fq/pkg/decode"
)

func chnaDecode(d *decode.D, size int64) {
d.FieldU16("num_tracks")
d.FieldU16("num_uids")

audioIdLen := (size - 4) / 40
d.FieldStructNArray("audio_ids", "audio_id", int64(audioIdLen), func(d *decode.D) {
d.FieldU16("track_index")
d.FieldUTF8("uid", 12)
d.FieldUTF8("track_format_id_reference", 14)
d.FieldUTF8("pack_format_id_reference", 11)
// Skip padding single byte
d.U8()
})
}

func axmlDecode(d *decode.D, size int64) {
// TODO(jmarnell): this chunk is all variable xml, so leave as is?
d.FieldRawLen("xml", size*8)
}
2 changes: 1 addition & 1 deletion format/riff/aiff.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func aiffDecode(d *decode.D) any {
}
return id, size
},
func(d *decode.D, id string, path path) (bool, any) {
func(d *decode.D, id string, path path, size int64) (bool, any) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size not needed anymore?

switch id {
case "FORM":
riffType = d.FieldUTF8("format", 4, d.StrAssert(aiffRiffType))
Expand Down
2 changes: 1 addition & 1 deletion format/riff/avi.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func aviDecodeEx(d *decode.D, ai format.AVI_In, extendedChunk bool) {
size := d.FieldU32("size")
return id, int64(size)
},
func(d *decode.D, id string, path path) (bool, any) {
func(d *decode.D, id string, path path, size int64) (bool, any) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size not needed anymore?

switch id {
case "RIFF":
foundRiffType = d.FieldUTF8("type", 4, d.StrAssert(requiredRiffType))
Expand Down
8 changes: 6 additions & 2 deletions format/riff/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ func (p path) topData() any {
return p[len(p)-1].data
}

func riffDecode(d *decode.D, path path, headFn func(d *decode.D, path path) (string, int64), chunkFn func(d *decode.D, id string, path path) (bool, any)) {
func riffDecode(d *decode.D, path path, headFn func(d *decode.D, path path) (string, int64), chunkFn func(d *decode.D, id string, path path, size int64) (bool, any)) {
id, size := headFn(d, path)

d.FramedFn(size*8, func(d *decode.D) {
hasChildren, data := chunkFn(d, id, path)
hasChildren, data := chunkFn(d, id, path, size)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses FramedFn so i think chunkFn will be decoding in a limited/framed bit range so i think you can use BitsLeft/Len etc to get how much is left

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have been doing it wrong, but that's what I tried initially, hope to get to revisit soon!

Copy link
Owner

@wader wader Aug 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okok yeah in this case i think relying on framing should work and i think it usually ends up with nicer code, let's try that first at least

if hasChildren {
np := append(path, pathEntry{id: id, data: data})
d.FieldArray("chunks", func(d *decode.D) {
Expand Down Expand Up @@ -58,6 +58,10 @@ var chunkIDDescriptions = scalar.StrMapDescription{

"dmlh": "Extended AVI header",

"chna": "<chna> Chunk, Track UIDs of Audio Definition Model",
"axml": "<axml> Chunk, BWF XML Metadata, e.g. for Audio Definition Model ambisonics and elements",
"dbmd": "Dolby Metadata, e.g. Atmos, AC3, Dolby Digital [Plus]",

"ISMP": "SMPTE timecode",
"IDIT": "Time and date digitizing commenced",
"IARL": "Archival Location. Indicates where the subject of the file is archived.",
Expand Down
Loading