github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/mpeg4audio/audio_specific_config.go (about)

     1  package mpeg4audio
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/bluenviron/mediacommon/pkg/bits"
     7  )
     8  
     9  // Config is an alias for AudioSpecificConfig.
    10  type Config = AudioSpecificConfig
    11  
    12  // AudioSpecificConfig is an AudioSpecificConfig.
    13  // Specification: ISO 14496-3, 1.6.2.1
    14  type AudioSpecificConfig struct {
    15  	Type         ObjectType
    16  	SampleRate   int
    17  	ChannelCount int
    18  
    19  	// SBR / PS specific
    20  	ExtensionType       ObjectType
    21  	ExtensionSampleRate int
    22  
    23  	FrameLengthFlag    bool
    24  	DependsOnCoreCoder bool
    25  	CoreCoderDelay     uint16
    26  }
    27  
    28  // Unmarshal decodes a Config.
    29  func (c *AudioSpecificConfig) Unmarshal(buf []byte) error {
    30  	pos := 0
    31  	return c.UnmarshalFromPos(buf, &pos)
    32  }
    33  
    34  // UnmarshalFromPos decodes a Config.
    35  func (c *AudioSpecificConfig) UnmarshalFromPos(buf []byte, pos *int) error {
    36  	tmp, err := bits.ReadBits(buf, pos, 5)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	c.Type = ObjectType(tmp)
    41  
    42  	switch c.Type {
    43  	case ObjectTypeAACLC, ObjectTypeSBR, ObjectTypePS:
    44  	default:
    45  		return fmt.Errorf("unsupported object type: %d", c.Type)
    46  	}
    47  
    48  	sampleRateIndex, err := bits.ReadBits(buf, pos, 4)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	switch {
    54  	case sampleRateIndex <= 12:
    55  		c.SampleRate = sampleRates[sampleRateIndex]
    56  
    57  	case sampleRateIndex == 0x0F:
    58  		tmp, err := bits.ReadBits(buf, pos, 24)
    59  		if err != nil {
    60  			return err
    61  		}
    62  		c.SampleRate = int(tmp)
    63  
    64  	default:
    65  		return fmt.Errorf("invalid sample rate index (%d)", sampleRateIndex)
    66  	}
    67  
    68  	channelConfig, err := bits.ReadBits(buf, pos, 4)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	switch {
    74  	case channelConfig == 0:
    75  		return fmt.Errorf("not yet supported")
    76  
    77  	case channelConfig >= 1 && channelConfig <= 6:
    78  		c.ChannelCount = int(channelConfig)
    79  
    80  	case channelConfig == 7:
    81  		c.ChannelCount = 8
    82  
    83  	default:
    84  		return fmt.Errorf("invalid channel configuration (%d)", channelConfig)
    85  	}
    86  
    87  	if c.Type == ObjectTypeSBR || c.Type == ObjectTypePS {
    88  		c.ExtensionType = c.Type
    89  
    90  		extensionSamplingFrequencyIndex, err := bits.ReadBits(buf, pos, 4)
    91  		if err != nil {
    92  			return err
    93  		}
    94  
    95  		switch {
    96  		case extensionSamplingFrequencyIndex <= 12:
    97  			c.ExtensionSampleRate = sampleRates[extensionSamplingFrequencyIndex]
    98  
    99  		case extensionSamplingFrequencyIndex == 0x0F:
   100  			tmp, err := bits.ReadBits(buf, pos, 24)
   101  			if err != nil {
   102  				return err
   103  			}
   104  			c.ExtensionSampleRate = int(tmp)
   105  
   106  		default:
   107  			return fmt.Errorf("invalid extension sample rate index (%d)", extensionSamplingFrequencyIndex)
   108  		}
   109  
   110  		tmp, err = bits.ReadBits(buf, pos, 5)
   111  		if err != nil {
   112  			return err
   113  		}
   114  		c.Type = ObjectType(tmp)
   115  
   116  		if c.Type != ObjectTypeAACLC {
   117  			return fmt.Errorf("unsupported object type: %d", c.Type)
   118  		}
   119  	}
   120  
   121  	c.FrameLengthFlag, err = bits.ReadFlag(buf, pos)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	c.DependsOnCoreCoder, err = bits.ReadFlag(buf, pos)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	if c.DependsOnCoreCoder {
   132  		tmp, err := bits.ReadBits(buf, pos, 14)
   133  		if err != nil {
   134  			return err
   135  		}
   136  		c.CoreCoderDelay = uint16(tmp)
   137  	}
   138  
   139  	extensionFlag, err := bits.ReadFlag(buf, pos)
   140  	if err != nil {
   141  		return err
   142  	}
   143  
   144  	if extensionFlag {
   145  		return fmt.Errorf("unsupported")
   146  	}
   147  
   148  	return nil
   149  }
   150  
   151  func (c AudioSpecificConfig) marshalSizeBits() int {
   152  	n := 5 + 4 + 2 + 1
   153  
   154  	_, ok := reverseSampleRates[c.SampleRate]
   155  	if !ok {
   156  		n += 28
   157  	} else {
   158  		n += 4
   159  	}
   160  
   161  	if c.ExtensionType == ObjectTypeSBR || c.ExtensionType == ObjectTypePS {
   162  		_, ok := reverseSampleRates[c.ExtensionSampleRate]
   163  		if !ok {
   164  			n += 28
   165  		} else {
   166  			n += 4
   167  		}
   168  		n += 5
   169  	}
   170  
   171  	if c.DependsOnCoreCoder {
   172  		n += 14
   173  	}
   174  
   175  	return n
   176  }
   177  
   178  func (c AudioSpecificConfig) marshalSize() int {
   179  	n := c.marshalSizeBits()
   180  
   181  	ret := n / 8
   182  	if (n % 8) != 0 {
   183  		ret++
   184  	}
   185  
   186  	return ret
   187  }
   188  
   189  // Marshal encodes a Config.
   190  func (c AudioSpecificConfig) Marshal() ([]byte, error) {
   191  	buf := make([]byte, c.marshalSize())
   192  	pos := 0
   193  
   194  	err := c.marshalTo(buf, &pos)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	return buf, nil
   200  }
   201  
   202  func (c AudioSpecificConfig) marshalTo(buf []byte, pos *int) error {
   203  	if c.ExtensionType == ObjectTypeSBR || c.ExtensionType == ObjectTypePS {
   204  		bits.WriteBits(buf, pos, uint64(c.ExtensionType), 5)
   205  	} else {
   206  		bits.WriteBits(buf, pos, uint64(c.Type), 5)
   207  	}
   208  
   209  	sampleRateIndex, ok := reverseSampleRates[c.SampleRate]
   210  	if !ok {
   211  		bits.WriteBits(buf, pos, uint64(15), 4)
   212  		bits.WriteBits(buf, pos, uint64(c.SampleRate), 24)
   213  	} else {
   214  		bits.WriteBits(buf, pos, uint64(sampleRateIndex), 4)
   215  	}
   216  
   217  	var channelConfig int
   218  	switch {
   219  	case c.ChannelCount >= 1 && c.ChannelCount <= 6:
   220  		channelConfig = c.ChannelCount
   221  
   222  	case c.ChannelCount == 8:
   223  		channelConfig = 7
   224  
   225  	default:
   226  		return fmt.Errorf("invalid channel count (%d)", c.ChannelCount)
   227  	}
   228  	bits.WriteBits(buf, pos, uint64(channelConfig), 4)
   229  
   230  	if c.ExtensionType == ObjectTypeSBR || c.ExtensionType == ObjectTypePS {
   231  		sampleRateIndex, ok := reverseSampleRates[c.ExtensionSampleRate]
   232  		if !ok {
   233  			bits.WriteBits(buf, pos, uint64(0x0F), 4)
   234  			bits.WriteBits(buf, pos, uint64(c.ExtensionSampleRate), 24)
   235  		} else {
   236  			bits.WriteBits(buf, pos, uint64(sampleRateIndex), 4)
   237  		}
   238  		bits.WriteBits(buf, pos, uint64(c.Type), 5)
   239  	}
   240  
   241  	if c.FrameLengthFlag {
   242  		bits.WriteBits(buf, pos, 1, 1)
   243  	} else {
   244  		bits.WriteBits(buf, pos, 0, 1)
   245  	}
   246  
   247  	if c.DependsOnCoreCoder {
   248  		bits.WriteBits(buf, pos, 1, 1)
   249  	} else {
   250  		bits.WriteBits(buf, pos, 0, 1)
   251  	}
   252  
   253  	if c.DependsOnCoreCoder {
   254  		bits.WriteBits(buf, pos, uint64(c.CoreCoderDelay), 14)
   255  	}
   256  
   257  	*pos++ // extensionFlag
   258  
   259  	return nil
   260  }