source: trunk/src/testing/bin/fileServer/misc/mmpython/audio/ac3info.py @ 4

Revision 4, 4.1 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1from mmpython import mediainfo
2import mmpython
3
4import struct
5
6# http://www.atsc.org/standards/a_52a.pdf
7# fscod: Sample rate code, 2 bits
8#  00  48
9#  01  44.1
10#  10  32
11#  11  reserved
12
13FSCOD = [ 48000, 44100, 32000, 0 ]
14
15# bsmod: Bit stream mode, 3 bits
16# bsmod acmod Type of Service
17#  000  any main audio service: complete main (CM)
18#  001  any main audio service: music and effects (ME)
19#  010  any associated service: visually impaired (VI)
20#  011  any associated service: hearing impaired (HI)
21#  100  any associated service: dialogue (D)
22#  101  any associated service: commentary (C)
23#  110  any associated service: emergency (E)
24#  111  001 associated service: voice over (VO)
25#  111  010 - 111  main audio service: karaoke
26#
27# acmod: Audio coding mode, 3 bits
28#  000  1+1 2 Ch1, Ch2
29#  001  1/0 1 C
30#  010  2/0 2 L, R
31#  011  3/0 3 L, C, R
32#  100  2/1 3 L, R, S
33#  101  3/1 4 L, C, R, S
34#  110  2/2 4 L, R, SL, SR
35#  111  3/2 5 L, C, R, SL, SR
36
37ACMOD = [ ( '1+1', 2, 'Ch1, Ch2' ),
38          ( '1/0', 1, 'C' ),
39          ( '2/0', 2, 'L, R' ),
40          ( '3/0', 3, 'L, C, R' ),
41          ( '2/1', 3, 'L, R, S' ),
42          ( '3/1', 4, 'L, C, R, S' ),
43          ( '2/2', 4, 'L, R, SL, SR' ),
44          ( '3/2', 5, 'L, C, R, SL, SR' ) ]
45           
46
47# dsurmod: Dolby surround mode, 2 bits
48#  00  not indicated
49#  01  Not Dolby Surround encoded
50#  10  Dolby Surround encoded
51#  11  reserved
52#
53# lfeon: Low frequency effects channel on, 1 bit
54# This bit has a value of 1 if the lfe (sub woofer) channel is on, and a
55# value of 0 if the lfe channel is off.
56#
57# frmsizcod:
58#  byte&0x3e = 0x00        \b, 32 kbit/s
59#  byte&0x3e = 0x02        \b, 40 kbit/s
60#  byte&0x3e = 0x04        \b, 48 kbit/s
61#  byte&0x3e = 0x06        \b, 56 kbit/s
62#  byte&0x3e = 0x08        \b, 64 kbit/s
63#  byte&0x3e = 0x0a        \b, 80 kbit/s
64#  byte&0x3e = 0x0c        \b, 96 kbit/s
65#  byte&0x3e = 0x0e        \b, 112 kbit/s
66#  byte&0x3e = 0x10        \b, 128 kbit/s
67#  byte&0x3e = 0x12        \b, 160 kbit/s
68#  byte&0x3e = 0x14        \b, 192 kbit/s
69#  byte&0x3e = 0x16        \b, 224 kbit/s
70#  byte&0x3e = 0x18        \b, 256 kbit/s
71#  byte&0x3e = 0x1a        \b, 320 kbit/s
72#  byte&0x3e = 0x1c        \b, 384 kbit/s
73#  byte&0x3e = 0x1e        \b, 448 kbit/s
74#  byte&0x3e = 0x20        \b, 512 kbit/s
75#  byte&0x3e = 0x22        \b, 576 kbit/s
76#  byte&0x3e = 0x24        \b, 640 kbit/s
77
78FRMSIZCOD = [ 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192,
79              224, 256, 320, 384, 448, 512, 576, 640 ]
80
81class AC3Info(mediainfo.MusicInfo):
82    def __init__(self,file):
83        mediainfo.MusicInfo.__init__(self)
84        if file.name.endswith('.ac3'):
85            # when the ending is ac3, force the detection. It may not be necessary
86            # the the header is at the beginning but in the first 2000 bytes
87            check_length = 1000
88        else:
89            check_length = 1
90        for i in range(check_length):
91            if file.read(2) == '\x0b\x77':
92                break
93        else:
94            self.valid = False
95            return
96
97        info = struct.unpack('<HBBBB',file.read(6))
98        self.samplerate = FSCOD[info[1] >> 6]
99        self.bitrate = FRMSIZCOD[(info[1] & 0x3F) >> 1] * 1000
100        bsmod = info[2] & 0x7
101        channels = ACMOD[info[3] >> 5]
102        acmod = info[3] >> 5
103        self.channels = ACMOD[acmod][1]
104        bits = 0
105        if acmod & 0x01 and not acmod == 0x01:
106            bits += 2
107        if acmod & 0x04:
108            bits += 2
109        if acmod == 0x02:
110            bits += 2
111
112        # info is now 5 bits of info[3] and all bits of info[4] ( == 13 bits)
113        # 'bits' bits (0-6) bits are information we don't need, after that,
114        # the bit we need is lfeon.
115        info = (((info[3] & 0x1F) << 8) + info[4])
116
117        # now we create the mask we need (based on 'bits')
118        # the bit number 13 - 'bits' is what we want to read
119        for i in range(13 - bits - 1):
120            info = info >> 1
121        if info & 1:
122            # subwover
123            self.channels += 1
124        self.valid = True
125        self.codec = 'AC3'
126        self.mime = 'audio/ac3'
127       
128mmpython.registertype( 'audio/ac3', ('ac3',), mediainfo.TYPE_MUSIC, AC3Info )
Note: See TracBrowser for help on using the repository browser.