1 
2 /***************************************************************************
3     copyright            : (C) 2002-6 by mean
4     email                : fixounet@free.fr
5 
6     Interface to Aften
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 #include <math.h>
19 #include "ADM_default.h"
20 #include "DIA_factory.h"
21 #include "DIA_coreToolkit.h"
22 #include "audioencoder.h"
23 #include "audioencoderInternal.h"
24 
25 //
26 extern "C"
27 {
28 #include "aften/aften.h"
29 };
30 #include "audioencoder_aften.h"
31 #include "aften_encoder_desc.cpp"
32 
33 #define _HANDLE ((AftenContext *)_handle)
34 #define AFTEN_DEFAULT_CONF {128}
35 static aften_encoder defaultConfig = AFTEN_DEFAULT_CONF;
36 
37 static bool configure (CONFcouple **setup);
38 static void getDefaultConfiguration(CONFcouple **c);
39 
40 /********************* Declare Plugin *****************************************************/
41 ADM_DECLARE_AUDIO_ENCODER_PREAMBLE(AUDMEncoder_Aften);
42 
43 static ADM_audioEncoder encoderDesc = {
44   ADM_AUDIO_ENCODER_API_VERSION,
45   create,			// Defined by macro automatically
46   destroy,			// Defined by macro automatically
47   configure,		//** put your own function here**
48   "Aften",
49   "AC3 (Aften)",
50   "Aften AC3 encoder plugin Mean/Gruntster 2008",
51   6,                    // Max channels
52   1,0,0,                // Version
53   WAV_AC3,
54   200,                  // Priority
55 
56   NULL,         //** put your own function here**
57   getDefaultConfiguration,
58   NULL
59 };
60 ADM_DECLARE_AUDIO_ENCODER_CONFIG();
61 
62 /******************* / Declare plugin*******************************************************/
63 
64 
65 /**
66     \fn AUDMEncoder_Aften
67 
68 */
69 
AUDMEncoder_Aften(AUDMAudioFilter * instream,bool globalHeader,CONFcouple * setup)70 AUDMEncoder_Aften::AUDMEncoder_Aften(AUDMAudioFilter * instream,bool globalHeader,
71     CONFcouple *setup)  :ADM_AudioEncoder    (instream,setup)
72 {
73   uint32_t channels;
74   ADM_info("[Aften] Creating aften\n");
75   channels=instream->getInfo()->channels;
76   _handle=(void *)new AftenContext;
77   memset(_handle,0,sizeof(AftenContext));
78   aften_set_defaults(_HANDLE);
79   wavheader.encoding=WAV_AC3;
80   _HANDLE->system.n_threads=1;
81   _globalHeader= globalHeader;
82   _config=defaultConfig;
83   if(setup) // load config if possible
84     ADM_paramLoad(setup,aften_encoder_param,&_config);
85 
86   switch(channels)
87   {
88     case 1:
89         outputChannelMapping[1] = ADM_CH_FRONT_LEFT;
90         break;
91     case 2:
92     	outputChannelMapping[0] = ADM_CH_FRONT_LEFT;
93     	outputChannelMapping[1] = ADM_CH_FRONT_RIGHT;
94       break;
95     default :
96 
97     CHANNEL_TYPE *f=outputChannelMapping;
98 
99         *f++ = ADM_CH_FRONT_LEFT;
100         *f++ = ADM_CH_FRONT_CENTER;
101         *f++ = ADM_CH_FRONT_RIGHT;
102 
103         *f++ = ADM_CH_REAR_LEFT;
104         *f++ = ADM_CH_REAR_RIGHT;
105 
106         *f++ = ADM_CH_LFE;
107         break;
108   }
109   ordered=new float[256*6*wavheader.channels];
110 };
111 
112 /**
113     \fn ~AUDMEncoder_Aften
114 
115 */
116 
~AUDMEncoder_Aften()117 AUDMEncoder_Aften::~AUDMEncoder_Aften()
118 {
119     ADM_info("[Aften] Deleting aften\n");
120     if(_handle)
121       aften_encode_close(_HANDLE);
122     delete(_HANDLE);
123     _handle=NULL;
124     if(ordered) delete [] ordered;
125     ordered=NULL;
126 };
127 
128 
129 /**
130     \fn initialize
131 
132 */
initialize(void)133 bool AUDMEncoder_Aften::initialize(void)
134 {
135 int ret=0;
136 unsigned int mask;
137 
138     if(FLOAT_TYPE_FLOAT!=aften_get_float_type())
139     {
140             ADM_error("Aften was configured to use double !");
141             return false;
142     }
143 
144     wavheader.byterate=(_config.bitrate*1000)/8;
145     _HANDLE->sample_format=A52_SAMPLE_FMT_FLT;
146     _HANDLE->channels=wavheader.channels;
147     _HANDLE->samplerate=wavheader.frequency;
148 
149     _HANDLE->params.bitrate=_config.bitrate;
150     switch(wavheader.channels)
151     {
152         case 1: mask = 0x04;  break;
153         case 2: mask = 0x03;  break;
154         case 3: mask = 0x07;  break;
155         case 4: mask = 0x107; break;
156         case 5: mask = 0x37;  break;
157         case 6: mask = 0x3F;  break;
158       }
159 
160 	aften_wav_channels_to_acmod(wavheader.channels, mask, &(_HANDLE->acmod), &(_HANDLE->lfe));
161 
162     int er= aften_encode_init(_HANDLE);
163     if(er<0)
164     {
165       ADM_warning("[Aften] init error %d\n",er);
166       return false;
167     }
168     _chunk=256*6*wavheader.channels;
169 
170     ADM_info("[Aften] Initialized with fd %u Channels %u bitrate %u\n",_HANDLE->samplerate,
171                                                                     _HANDLE->channels,_HANDLE->params.bitrate);
172     return true;
173 }
174 
175 
176 /**
177         \fn encode
178 */
encode(uint8_t * dest,uint32_t * len,uint32_t * samples)179 bool    AUDMEncoder_Aften::encode(uint8_t *dest, uint32_t *len, uint32_t *samples)
180 {
181   uint32_t count=0;
182   int r;
183   void *ptr;
184 _again:
185         *len = 0;
186         _chunk=256*6*wavheader.channels;
187         if(!refillBuffer(_chunk ))
188         {
189           return 0;
190         }
191 
192         ADM_assert(tmptail>=tmphead);
193         reorder(&(tmpbuffer[tmphead]),ordered,256*6,_incoming->getChannelMapping(),outputChannelMapping);
194         r=aften_encode_frame(_HANDLE, dest,(void *)ordered
195 #ifndef AFTEN_08
196       ,256*6
197 #endif
198         );
199         if(r<0)
200         {
201           printf("[Aften] Encoding error %d\n",r);
202           return 0;
203         }
204 
205         *samples=256*6;
206         *len=r;
207         tmphead+=_chunk;
208         return 1;
209 }
210 
211 /**
212     \fn configure
213 */
214 #define SZT(x) sizeof(x)/sizeof(diaMenuEntry )
215 #define BITRATE(x) {x,QT_TRANSLATE_NOOP("aften",#x)}
216 
configure(CONFcouple ** setup)217 bool configure (CONFcouple **setup)
218 {
219  int ret=0;
220     aften_encoder config=defaultConfig;
221     if(*setup)
222     {
223         ADM_paramLoad(*setup,aften_encoder_param,&config);
224     }
225 
226 
227     diaMenuEntry bitrateM[]={
228                               BITRATE(56),
229                               BITRATE(64),
230                               BITRATE(80),
231                               BITRATE(96),
232                               BITRATE(112),
233                               BITRATE(128),
234                               BITRATE(160),
235                               BITRATE(192),
236                               BITRATE(224),
237                               BITRATE(384),
238                               BITRATE(448)
239                           };
240     diaElemMenu bitrate(&(config.bitrate),   QT_TRANSLATE_NOOP("aften","_Bitrate:"), SZT(bitrateM),bitrateM);
241 
242 
243 
244     diaElem *elems[]={&bitrate};
245 
246     if( diaFactoryRun(QT_TRANSLATE_NOOP("aften","Aften Configuration"),1,elems))
247     {
248       if(*setup) delete *setup;
249       *setup=NULL;
250       ADM_paramSave(setup,aften_encoder_param,&config);
251       defaultConfig=config;
252       return true;
253     }
254     return false;
255 }
256 
getDefaultConfiguration(CONFcouple ** c)257 void getDefaultConfiguration(CONFcouple **c)
258 {
259 	aften_encoder config = AFTEN_DEFAULT_CONF;
260 
261 	ADM_paramSave(c, aften_encoder_param, &config);
262 }
263 // EOF
264