{-# LANGUAGE UndecidableInstances #-} -- | @mp4a@ Audio sample entry according to ISO 14496-14 module Data.ByteString.Mp4.Boxes.AudioSpecificConfig where import Data.ByteString.IsoBaseFileFormat.ReExports import Data.ByteString.Mp4.Boxes.DecoderSpecificInfo -- * Decoder Configuration for ISO 14496-3 (Audio) -- | A audio config using 'AudioConfigAacMinimal' for AAC-LC. type AudioConfigAacLc freq channels = AudioConfigAacMinimal 'AacLc DefaultGASpecificConfig freq channels -- | A audio config using 'AudioConfigSbrExplicitHierachical' for HE-AAC (v1) in -- dual rate mode. type AudioConfigHeAac freq channels = AudioConfigSbrExplicitHierachical 'AacLc DefaultGASpecificConfig freq channels freq -- | A minimalistic audio config without sync and error protection data AudioConfigAacMinimal :: AudioObjectTypeId -> Extends AudioSubConfig -> Extends (EnumOf SamplingFreqTable) -> Extends (EnumOf ChannelConfigTable) -> Extends (DecoderSpecificInfo 'AudioIso14496_3 'AudioStream) type instance From (AudioConfigAacMinimal aoId subCfg freq channels) = ('MkDecoderSpecificInfo (AudioConfigCommon aoId freq channels (BitRecordOfAudioSubConfig subCfg))) -- | A audio config with SBR signalled explicit and hierachical data AudioConfigSbrExplicitHierachical :: AudioObjectTypeId -> Extends AudioSubConfig -> Extends (EnumOf SamplingFreqTable) -> Extends (EnumOf ChannelConfigTable) -> Extends (EnumOf SamplingFreqTable) -- extension SamplingFrequency -> Extends (DecoderSpecificInfo 'AudioIso14496_3 'AudioStream) type instance From (AudioConfigSbrExplicitHierachical aoId subCfg freq channels extFreq) = 'MkDecoderSpecificInfo (AudioConfigCommon 'Sbr freq channels (BitRecordOfEnum extFreq :+: AudioObjectTypeRec aoId :+: BitRecordOfAudioSubConfig subCfg)) -- | Common header for audio specific config type AudioConfigCommon aoId samplingFrequencyIndex channels rest = AudioObjectTypeRec aoId :+: BitRecordOfEnum samplingFrequencyIndex :+: BitRecordOfEnum channels :+: rest -- ** Audio Object Type data AudioObjectTypeId = AacMain -- ^ ISO 14496-4 subpart 4 | AacLc -- ^ ISO 14496-4 subpart 4 | AacSsr -- ^ ISO 14496-4 subpart 4 | AacLtp -- ^ ISO 14496-4 subpart 4 | Sbr -- ^ ISO 14496-4 subpart 4 | AacScalable -- ^ ISO 14496-4 subpart 4 | TwinVq -- ^ ISO 14496-4 subpart 4 | Celp -- ^ ISO 14496-4 subpart 3 | Hvxc -- ^ ISO 14496-4 subpart 2 | AoReserved1 | AoReserved2 | Ttsi -- ^ ISO 14496-4 subpart 6 | MainSunthetic -- ^ ISO 14496-4 subpart 5 | WavetableSynthesis -- ^ ISO 14496-4 subpart 5 | GeneralMidi -- ^ ISO 14496-4 subpart 5 | AlgorithmicSynthesisAndAudioFx -- ^ ISO 14496-4 subpart 5 | ErAacLc -- ^ ISO 14496-4 subpart 4 | AoReserved3 | ErAacLtp -- ^ ISO 14496-4 subpart 4 | ErAacScalable -- ^ ISO 14496-4 subpart 4 | ErTwinVq -- ^ ISO 14496-4 subpart 4 | ErBsac -- ^ ISO 14496-4 subpart 4 | ErAacLd -- ^ ISO 14496-4 subpart 4 | ErCelp -- ^ ISO 14496-4 subpart 3 | ErHvxc -- ^ ISO 14496-4 subpart 2 | ErHiln -- ^ ISO 14496-4 subpart 7 | ErParametric -- ^ ISO 14496-4 subpart 2 or 7 | Ssc -- ^ ISO 14496-4 subpart 8 | AoReserved4 | AoReserved5 | AoCustom | AoLayer1 -- ^ ISO 14496-4 subpart 9 | AoLayer2 -- ^ ISO 14496-4 subpart 9 | AoLayer3 -- ^ ISO 14496-4 subpart 9 | AoDst -- ^ ISO 14496-4 subpart 10 | AotInvalid type instance FromEnum AudioObjectTypeId 'AotInvalid = 0 type instance FromEnum AudioObjectTypeId 'AacMain = 1 type instance FromEnum AudioObjectTypeId 'AacLc = 2 type instance FromEnum AudioObjectTypeId 'AacSsr = 3 type instance FromEnum AudioObjectTypeId 'AacLtp = 4 type instance FromEnum AudioObjectTypeId 'Sbr = 5 type instance FromEnum AudioObjectTypeId 'AacScalable = 6 type instance FromEnum AudioObjectTypeId 'TwinVq = 7 type instance FromEnum AudioObjectTypeId 'Celp = 8 type instance FromEnum AudioObjectTypeId 'Hvxc = 9 type instance FromEnum AudioObjectTypeId 'AoReserved1 = 10 type instance FromEnum AudioObjectTypeId 'AoReserved2 = 11 type instance FromEnum AudioObjectTypeId 'Ttsi = 12 type instance FromEnum AudioObjectTypeId 'MainSunthetic = 13 type instance FromEnum AudioObjectTypeId 'WavetableSynthesis = 14 type instance FromEnum AudioObjectTypeId 'GeneralMidi = 15 type instance FromEnum AudioObjectTypeId 'AlgorithmicSynthesisAndAudioFx = 16 type instance FromEnum AudioObjectTypeId 'ErAacLc = 17 type instance FromEnum AudioObjectTypeId 'AoReserved3 = 18 type instance FromEnum AudioObjectTypeId 'ErAacLtp = 19 type instance FromEnum AudioObjectTypeId 'ErAacScalable = 20 type instance FromEnum AudioObjectTypeId 'ErTwinVq = 21 type instance FromEnum AudioObjectTypeId 'ErBsac = 22 type instance FromEnum AudioObjectTypeId 'ErAacLd = 23 type instance FromEnum AudioObjectTypeId 'ErCelp = 24 type instance FromEnum AudioObjectTypeId 'ErHvxc = 25 type instance FromEnum AudioObjectTypeId 'ErHiln = 26 type instance FromEnum AudioObjectTypeId 'ErParametric = 27 type instance FromEnum AudioObjectTypeId 'Ssc = 28 type instance FromEnum AudioObjectTypeId 'AoReserved4 = 29 type instance FromEnum AudioObjectTypeId 'AoReserved5 = 30 type instance FromEnum AudioObjectTypeId 'AoCustom = 31 type instance FromEnum AudioObjectTypeId 'AoLayer1 = 32 type instance FromEnum AudioObjectTypeId 'AoLayer2 = 33 type instance FromEnum AudioObjectTypeId 'AoLayer3 = 34 type instance FromEnum AudioObjectTypeId 'AoDst = 35 type AudioObjectTypeRec n = AudioObjectTypeField1 (FromEnum AudioObjectTypeId n) .+: AudioObjectTypeField2 (FromEnum AudioObjectTypeId n) type family AudioObjectTypeField1 (n :: Nat) :: Extends (BitRecordField ('MkFieldBits :: BitField (B 5) Nat 5)) where AudioObjectTypeField1 n = If (n <=? 30) (Field 5 := n) (Field 5 := 31) type family AudioObjectTypeField2 (n :: Nat) :: BitRecord where AudioObjectTypeField2 n = If (n <=? 30) 'EmptyBitRecord ('BitRecordMember (Field 6 := (n - 31))) -- *** Sampling Frequency type SamplingFreq = ExtEnum SamplingFreqTable 4 'SFCustom (Field 24) data SamplingFreqTable = SF96000 | SF88200 | SF64000 | SF48000 | SF44100 | SF32000 | SF24000 | SF22050 | SF16000 | SF12000 | SF11025 | SF8000 | SF7350 | SFReserved1 | SFReserved2 | SFCustom type instance FromEnum SamplingFreqTable 'SF96000 = 0 type instance FromEnum SamplingFreqTable 'SF88200 = 1 type instance FromEnum SamplingFreqTable 'SF64000 = 2 type instance FromEnum SamplingFreqTable 'SF48000 = 3 type instance FromEnum SamplingFreqTable 'SF44100 = 4 type instance FromEnum SamplingFreqTable 'SF32000 = 5 type instance FromEnum SamplingFreqTable 'SF24000 = 6 type instance FromEnum SamplingFreqTable 'SF22050 = 7 type instance FromEnum SamplingFreqTable 'SF16000 = 8 type instance FromEnum SamplingFreqTable 'SF12000 = 9 type instance FromEnum SamplingFreqTable 'SF11025 = 0xa type instance FromEnum SamplingFreqTable 'SF8000 = 0xb type instance FromEnum SamplingFreqTable 'SF7350 = 0xc type instance FromEnum SamplingFreqTable 'SFReserved1 = 0xd type instance FromEnum SamplingFreqTable 'SFReserved2 = 0xe type instance FromEnum SamplingFreqTable 'SFCustom = 0xf sampleRateToNumber :: Num a => SamplingFreqTable -> a sampleRateToNumber SF96000 = 96000 sampleRateToNumber SF88200 = 88200 sampleRateToNumber SF64000 = 64000 sampleRateToNumber SF48000 = 48000 sampleRateToNumber SF44100 = 44100 sampleRateToNumber SF32000 = 32000 sampleRateToNumber SF24000 = 24000 sampleRateToNumber SF22050 = 22050 sampleRateToNumber SF16000 = 16000 sampleRateToNumber SF12000 = 12000 sampleRateToNumber SF11025 = 11025 sampleRateToNumber SF8000 = 8000 sampleRateToNumber SF7350 = 7350 sampleRateToNumber _ = 0 sampleRateToEnum :: SamplingFreqTable -> EnumValue SamplingFreqTable sampleRateToEnum SF96000 = MkEnumValue (Proxy @'SF96000) sampleRateToEnum SF88200 = MkEnumValue (Proxy @'SF88200) sampleRateToEnum SF64000 = MkEnumValue (Proxy @'SF64000) sampleRateToEnum SF48000 = MkEnumValue (Proxy @'SF48000) sampleRateToEnum SF44100 = MkEnumValue (Proxy @'SF44100) sampleRateToEnum SF32000 = MkEnumValue (Proxy @'SF32000) sampleRateToEnum SF24000 = MkEnumValue (Proxy @'SF24000) sampleRateToEnum SF22050 = MkEnumValue (Proxy @'SF22050) sampleRateToEnum SF16000 = MkEnumValue (Proxy @'SF16000) sampleRateToEnum SF12000 = MkEnumValue (Proxy @'SF12000) sampleRateToEnum SF11025 = MkEnumValue (Proxy @'SF11025) sampleRateToEnum SF8000 = MkEnumValue (Proxy @'SF8000) sampleRateToEnum SF7350 = MkEnumValue (Proxy @'SF7350) sampleRateToEnum SFReserved1 = MkEnumValue (Proxy @'SFReserved1) sampleRateToEnum SFReserved2 = MkEnumValue (Proxy @'SFReserved2) sampleRateToEnum SFCustom = MkEnumValue (Proxy @'SFCustom) -- *** Channel Config (Mono, Stereo, 7-1 Surround, ...) type ChannelConfig = FixedEnum ChannelConfigTable 4 data ChannelConfigTable = GasChannelConfig | SingleChannel | ChannelPair | SinglePair | SinglePairSingle | SinglePairPair | SinglePairPairLfe | SinglePairPairPairLfe type instance FromEnum ChannelConfigTable 'GasChannelConfig = 0 type instance FromEnum ChannelConfigTable 'SingleChannel = 1 type instance FromEnum ChannelConfigTable 'ChannelPair = 2 type instance FromEnum ChannelConfigTable 'SinglePair = 3 type instance FromEnum ChannelConfigTable 'SinglePairSingle = 4 type instance FromEnum ChannelConfigTable 'SinglePairPair = 5 type instance FromEnum ChannelConfigTable 'SinglePairPairLfe = 6 type instance FromEnum ChannelConfigTable 'SinglePairPairPairLfe = 7 channelConfigToNumber :: Num a => ChannelConfigTable -> a channelConfigToNumber GasChannelConfig = 0 channelConfigToNumber SingleChannel = 1 channelConfigToNumber ChannelPair = 2 channelConfigToNumber SinglePair = 3 channelConfigToNumber SinglePairSingle = 4 channelConfigToNumber SinglePairPair = 5 channelConfigToNumber SinglePairPairLfe = 6 channelConfigToNumber SinglePairPairPairLfe = 7 channelConfigToEnum :: ChannelConfigTable -> EnumValue ChannelConfigTable channelConfigToEnum GasChannelConfig = MkEnumValue (Proxy @'GasChannelConfig) channelConfigToEnum SingleChannel = MkEnumValue (Proxy @'SingleChannel) channelConfigToEnum ChannelPair = MkEnumValue (Proxy @'ChannelPair) channelConfigToEnum SinglePair = MkEnumValue (Proxy @'SinglePair) channelConfigToEnum SinglePairSingle = MkEnumValue (Proxy @'SinglePairSingle) channelConfigToEnum SinglePairPair = MkEnumValue (Proxy @'SinglePairPair) channelConfigToEnum SinglePairPairLfe = MkEnumValue (Proxy @'SinglePairPairLfe) channelConfigToEnum SinglePairPairPairLfe = MkEnumValue (Proxy @'SinglePairPairPairLfe) -- ** More Specific audio decoder config data AudioSubConfig :: Type type family BitRecordOfAudioSubConfig (x :: Extends AudioSubConfig) :: BitRecord data GASpecificConfig (frameLenFlag :: Extends (FieldValue "frameLenFlag" Bool)) (coreCoderDelay :: Maybe (Extends (FieldValue "coreCoderDelay" Nat))) (extension :: Extends GASExtension) :: Extends AudioSubConfig type DefaultGASpecificConfig = GASpecificConfig (StaticFieldValue "frameLenFlag" 'False) 'Nothing MkGASExtension type instance From (GASpecificConfig fl cd ext) = TypeError ('Text "AudioSubConfig is abstract!") type instance BitRecordOfAudioSubConfig (GASpecificConfig fl cd ext) = ( Flag :~ fl .+: FlagJust cd .+: Field 14 :+? cd :+: BitRecordOfGASExtension ext ) -- | TODO implment that GAS extensions data GASExtension data MkGASExtension :: Extends GASExtension type BitRecordOfGASExtension (x :: Extends GASExtension) = 'BitRecordMember ("has-gas-extension" @: Flag := 'False)