1
1
mirror of https://github.com/wader/fq.git synced 2024-11-27 14:14:58 +03:00
fq/format/mpeg/mpeg_asc.go
Mattias Wadman 2fc0a71a47 decode: Refactor scalar usage
Move scalar into own package.
Split scalar code into decode related scalar code (that reads etc) and
scalar code that just transform the scalar value.
Use a scalar.Mapper interface instead of just a function.
Make mappers, assert and validat impement the interface.
2021-12-02 17:39:26 +01:00

74 lines
1.9 KiB
Go

package mpeg
// https://wiki.multimedia.cx/index.php/MPEG-4_Audio
import (
"github.com/wader/fq/format"
"github.com/wader/fq/format/registry"
"github.com/wader/fq/pkg/decode"
"github.com/wader/fq/pkg/scalar"
)
func init() {
registry.MustRegister(decode.Format{
Name: format.MPEG_ASC,
Description: "MPEG-4 Audio Specific Config",
DecodeFn: ascDecoder,
})
}
var frequencyIndexHz = map[uint64]int{
0x0: 96000,
0x1: 88200,
0x2: 64000,
0x3: 48000,
0x4: 44100,
0x5: 32000,
0x6: 24000,
0x7: 22050,
0x8: 16000,
0x9: 12000,
0xa: 11025,
0xb: 8000,
0xc: 7350,
0xd: -1,
0xe: -1,
0xf: -1,
}
var channelConfigurationNames = scalar.UToScalar{
0: {Description: "defined in AOT Specifc Config"},
1: {Description: "front-center"},
2: {Description: "front-left, front-right"},
3: {Description: "front-center, front-left, front-right"},
4: {Description: "front-center, front-left, front-right, back-center"},
5: {Description: "front-center, front-left, front-right, back-left, back-right"},
6: {Description: "front-center, front-left, front-right, back-left, back-right, LFE-channel"},
7: {Description: "front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel"},
}
func ascDecoder(d *decode.D, in interface{}) interface{} {
objectType := d.FieldUFn("object_type", func(d *decode.D) uint64 {
n := d.U5()
if n == 31 {
n = 32 + d.U6()
}
return n
}, format.MPEGAudioObjectTypeNames)
d.FieldUScalarFn("sampling_frequency", func(d *decode.D) scalar.S {
v := d.U4()
if v == 15 {
return scalar.S{Actual: d.U24()}
}
if f, ok := frequencyIndexHz[v]; ok {
return scalar.S{Actual: v, Sym: f}
}
return scalar.S{Description: "invalid"}
})
d.FieldU4("channel_configuration", channelConfigurationNames)
// TODO: GASpecificConfig etc
d.FieldRawLen("var_aot_or_byte_align", d.BitsLeft())
return format.MPEGASCOut{ObjectType: int(objectType)}
}