r1053: Add Russian translation.
[cinelerra_cv.git] / libmpeg3 / audio / ac3.c
blobdc50e88d71a6d90750a28bd88bca8b499ffa6d1b
1 #include <stdint.h>
2 #include <stdio.h>
4 #include <a52dec/a52.h>
5 #include "mpeg3private.h"
6 #include "mpeg3protos.h"
8 #include <string.h>
11 mpeg3_ac3_t* mpeg3_new_ac3()
13 mpeg3_ac3_t *result = calloc(1, sizeof(mpeg3_ac3_t));
14 result->stream = mpeg3bits_new_stream(0, 0);
15 result->state = a52_init(0);
16 result->output = a52_samples(result->state);
17 return result;
20 void mpeg3_delete_ac3(mpeg3_ac3_t *audio)
22 mpeg3bits_delete_stream(audio->stream);
23 a52_free(audio->state);
24 free(audio);
28 /* Return 1 if it isn't an AC3 header */
29 int mpeg3_ac3_check(unsigned char *header)
31 int flags, samplerate, bitrate;
32 return !a52_syncinfo(header,
33 &flags,
34 &samplerate,
35 &bitrate);
38 /* Decode AC3 header */
39 int mpeg3_ac3_header(mpeg3_ac3_t *audio, unsigned char *header)
41 int result = 0;
42 audio->flags = 0;
44 //printf("mpeg3_ac3_header %02x%02x%02x%02x%02x%02x%02x%02x\n", header[0], header[1], header[2], header[3], header[4], header[5], header[6], header[7]);
45 result = a52_syncinfo(header,
46 &audio->flags,
47 &audio->samplerate,
48 &audio->bitrate);
51 if(result)
53 //printf("%d\n", result);
54 audio->framesize = result;
55 audio->channels = 0;
57 if(audio->flags & A52_LFE)
58 audio->channels++;
60 * printf("mpeg3_ac3_header %08x %08x\n",
61 * audio->flags & A52_LFE,
62 * audio->flags & A52_CHANNEL_MASK);
64 switch(audio->flags & A52_CHANNEL_MASK)
66 case A52_CHANNEL:
67 audio->channels++;
68 break;
69 case A52_MONO:
70 audio->channels++;
71 break;
72 case A52_STEREO:
73 audio->channels += 2;
74 break;
75 case A52_3F:
76 audio->channels += 3;
77 break;
78 case A52_2F1R:
79 audio->channels += 3;
80 break;
81 case A52_3F1R:
82 audio->channels += 4;
83 break;
84 case A52_2F2R:
85 audio->channels += 4;
86 break;
87 case A52_3F2R:
88 audio->channels += 5;
89 break;
90 case A52_DOLBY:
91 audio->channels += 2;
92 break;
93 default:
94 printf("mpeg3_ac3_header: unknown channel code: %p\n", audio->flags & A52_CHANNEL_MASK);
95 break;
98 //printf("mpeg3_ac3_header 1 %d\n", audio->channels);
99 return result;
103 int mpeg3audio_doac3(mpeg3_ac3_t *audio,
104 char *frame,
105 int frame_size,
106 float **output,
107 int render)
109 int output_position = 0;
110 sample_t level = 1;
111 int i, j, k, l;
113 //printf("mpeg3audio_doac3 1\n");
114 a52_frame(audio->state,
115 frame,
116 &audio->flags,
117 &level,
119 //printf("mpeg3audio_doac3 2\n");
120 a52_dynrng(audio->state, NULL, NULL);
121 //printf("mpeg3audio_doac3 3\n");
122 for(i = 0; i < 6; i++)
124 if(!a52_block(audio->state))
126 l = 0;
127 if(render)
129 // Remap the channels to conform to encoders.
130 for(j = 0; j < audio->channels; j++)
132 int dst_channel = j;
134 // Make LFE last channel.
135 // Shift all other channels down 1.
136 if((audio->flags & A52_LFE))
138 if(j == 0)
139 dst_channel = audio->channels - 1;
140 else
141 dst_channel--;
144 // Swap front left and center for certain configurations
145 switch(audio->flags & A52_CHANNEL_MASK)
147 case A52_3F:
148 case A52_3F1R:
149 case A52_3F2R:
150 if(dst_channel == 0) dst_channel = 1;
151 else
152 if(dst_channel == 1) dst_channel = 0;
153 break;
156 for(k = 0; k < 256; k++)
158 output[dst_channel][output_position + k] = ((sample_t*)audio->output)[l];
159 l++;
163 output_position += 256;
168 return output_position;