github.com/bluenviron/mediacommon@v1.9.3/pkg/codecs/ac3/sync_info.go (about)

     1  package ac3
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // ATSC, AC-3, Table 5.18
     8  var frameSizes = [][]int{
     9  	{64, 69, 96},
    10  	{64, 70, 96},
    11  	{80, 87, 120},
    12  	{80, 88, 120},
    13  	{96, 104, 144},
    14  	{96, 105, 144},
    15  	{112, 121, 168},
    16  	{112, 122, 168},
    17  	{128, 139, 192},
    18  	{128, 140, 192},
    19  	{160, 174, 240},
    20  	{160, 175, 240},
    21  	{192, 208, 288},
    22  	{192, 209, 288},
    23  	{224, 243, 336},
    24  	{224, 244, 336},
    25  	{256, 278, 384},
    26  	{256, 279, 384},
    27  	{320, 348, 480},
    28  	{320, 349, 480},
    29  	{384, 417, 576},
    30  	{384, 418, 576},
    31  	{448, 487, 672},
    32  	{448, 488, 672},
    33  	{512, 557, 768},
    34  	{512, 558, 768},
    35  	{640, 696, 960},
    36  	{640, 697, 960},
    37  	{768, 835, 1152},
    38  	{768, 836, 1152},
    39  	{896, 975, 1344},
    40  	{896, 976, 1344},
    41  	{1024, 1114, 1536},
    42  	{1024, 1115, 1536},
    43  	{1152, 1253, 1728},
    44  	{1152, 1254, 1728},
    45  	{1280, 1393, 1920},
    46  	{1280, 1394, 1920},
    47  }
    48  
    49  // SyncInfo is a synchronization information.
    50  // Specification: ATSC, AC-3, Table 5.1
    51  type SyncInfo struct {
    52  	Fscod      uint8
    53  	Frmsizecod uint8
    54  }
    55  
    56  // Unmarshal decodes a SyncInfo.
    57  func (s *SyncInfo) Unmarshal(frame []byte) error {
    58  	if len(frame) < 5 {
    59  		return fmt.Errorf("not enough bits")
    60  	}
    61  
    62  	if frame[0] != 0x0B || frame[1] != 0x77 {
    63  		return fmt.Errorf("invalid sync word")
    64  	}
    65  
    66  	s.Fscod = frame[4] >> 6
    67  	if s.Fscod >= 3 {
    68  		return fmt.Errorf("invalid fscod")
    69  	}
    70  
    71  	s.Frmsizecod = frame[4] & 0x3f
    72  	if s.Frmsizecod >= 38 {
    73  		return fmt.Errorf("invalid frmsizecod")
    74  	}
    75  
    76  	return nil
    77  }
    78  
    79  // FrameSize returns the frame size.
    80  func (s SyncInfo) FrameSize() int {
    81  	return frameSizes[s.Frmsizecod][s.Fscod] * 2
    82  }
    83  
    84  // SampleRate returns the frame sample rate.
    85  func (s SyncInfo) SampleRate() int {
    86  	switch s.Fscod {
    87  	case 0:
    88  		return 48000
    89  	case 1:
    90  		return 44100
    91  	default:
    92  		return 32000
    93  	}
    94  }