2310a19fb62c409fdab4e451f0bef2ae686e5044
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / audio / ac3.C
1 #include "../libzmpeg3.h"
2
3 zaudio_decoder_ac3_t::
4 audio_decoder_ac3_t()
5 {
6   stream = new bits_t(0, 0);
7   state = a52_init(0);
8   output = a52_samples(state);
9 }
10
11 zaudio_decoder_ac3_t::
12 ~audio_decoder_ac3_t()
13 {
14   delete stream;
15   a52_free(state);
16 }
17
18
19 /* Return 1 if it isn't an AC3 header */
20 int zaudio_decoder_ac3_t::
21 ac3_check(uint8_t *header)
22 {
23   int flags, samplerate, bitrate;
24   return !a52_syncinfo(header, &flags, &samplerate, &bitrate);
25 }
26
27 /* Decode AC3 header */
28 int zaudio_decoder_ac3_t::
29 ac3_header(uint8_t *header)
30 {
31   int result = 0;
32   flags = 0;
33 //zmsgs("%02x%02x%02x%02x%02x%02x%02x%02x\n",
34 //  header[0], header[1], header[2], header[3],
35 //  header[4], header[5], header[6], header[7]);
36   result = a52_syncinfo(header, &flags, &samplerate, &bitrate);
37
38   if( result ) {
39 //zmsgs("%d\n", result);
40     framesize = result;
41     channels = 0;
42
43     if( (flags & A52_LFE) != 0 )
44       ++channels;
45 //zmsgs("%08x %08x\n", (flags & A52_LFE), (flags & A52_CHANNEL_MASK));
46     switch( (flags & A52_CHANNEL_MASK) ) {
47       case A52_CHANNEL: ++channels;  break;
48       case A52_MONO:    ++channels;  break;
49       case A52_STEREO:  channels += 2;  break;
50       case A52_3F:      channels += 3;  break;
51       case A52_2F1R:    channels += 3;  break;
52       case A52_3F1R:    channels += 4;  break;
53       case A52_2F2R:    channels += 4;  break;
54       case A52_3F2R:    channels += 5;  break;
55       case A52_DOLBY:   channels += 2;  break;
56       default:
57         zmsgs("unknown channel code: %08x\n", (flags & A52_CHANNEL_MASK));
58         break;
59     }
60   }
61 //zmsgs("1 %d\n", channels);
62   return result;
63 }
64
65
66 int zaudio_decoder_ac3_t::
67 do_ac3(uint8_t *zframe, int zframe_size, float **zoutput, int render)
68 {
69   int output_position = 0;
70   sample_t level = 1;
71   int i, j, l;
72 //zmsgs("1\n");
73   a52_frame(state, zframe, &flags, &level, 0);
74 //zmsgs("2\n");
75   a52_dynrng(state, NULL, NULL);
76 //zmsgs("3\n");
77   for( i=0; i < 6; ++i ) {
78     if( !a52_block(state) ) {
79       l = 0;
80       if( render ) {
81         /* Remap the channels to conform to encoders. */
82         for( j=0; j < channels; ++j ) {
83           int dst_channel = j;
84           /* Make LFE last channel. */
85           /* Shift all other channels down 1. */
86           if( (flags & A52_LFE) != 0 )
87             dst_channel = j == 0 ? channels-1 : dst_channel-1;
88           /* Swap front left and center for certain configurations */
89           switch( (flags & A52_CHANNEL_MASK) ) {
90             case A52_3F:
91             case A52_3F1R:
92             case A52_3F2R:
93               if( dst_channel == 0 ) dst_channel = 1;
94               else if( dst_channel == 1 ) dst_channel = 0;
95               break;
96           }
97
98           memmove(zoutput[dst_channel]+output_position,
99               output+l, 256*sizeof(float));
100           l += 256;
101         }
102       }
103       output_position += 256;
104     }
105   }
106
107   return output_position;
108 }
109