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