1 /***************************************************************************
2 \file audiofilter.h
3 \brief Creates destroy audio filters
4 (c) 2006 Mean , fixounet@free.fr
5 ***************************************************************************/
6
7 /***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16
17 #include "ADM_cpp.h"
18 using std::string;
19 #include "ADM_default.h"
20 #include <math.h>
21
22 #include "audiofilter_bridge.h"
23 #include "audiofilter_access.h"
24 #include "audiofilter_internal.h"
25 #include "audiofilter_conf.h"
26 #include "audiofilter_film2pal.h"
27 #include "prefs.h"
28 VectorOfAudioFilter PlaybackVector;
29 extern ADM_Composer *video_body;
30
31 //
32 bool ADM_buildFilterChain(ADM_edAudioTrack *source,VectorOfAudioFilter *vec,ADM_AUDIOFILTER_CONFIG *config);
33 bool ADM_emptyFilterChain(VectorOfAudioFilter *vec);
34 /**
35 \fn createPlaybackFilter
36 \brief Create a float output filter for playback
37 @param StartTime in us
38 @param shift in ms
39 */
createPlaybackFilter(uint64_t startTime,int32_t shift)40 AUDMAudioFilter *createPlaybackFilter(uint64_t startTime,int32_t shift)
41 {
42 //
43 ADM_edAudioTrack *trk=video_body->getDefaultEdAudioTrack();
44 if(!trk) return NULL;
45 trk->goToTime(startTime);
46 //
47 uint32_t downmix;
48 ADM_AUDIOFILTER_CONFIG playback;
49 playback.startTimeInUs=startTime;
50 playback.shiftInMs=shift;
51 if(shift)
52 playback.shiftEnabled=true;
53 else
54 playback.shiftEnabled=false;
55 playback.mixerEnabled=true;
56 if(prefs->get(DEFAULT_DOWNMIXING,&downmix)!=RC_OK)
57 {
58 downmix=0;
59 }
60 switch (downmix) {
61 case 0:
62 playback.mixerEnabled=false;
63 break;
64 case 1:
65
66 playback.mixerConf=CHANNEL_STEREO;
67 break;
68 case 2:
69
70 playback.mixerConf=CHANNEL_DOLBY_PROLOGIC;
71 break;
72 case 3:
73
74 playback.mixerConf=CHANNEL_DOLBY_PROLOGIC2;
75 break;
76 default:
77 ADM_assert(0);break;
78 }
79
80
81 // Fetch mixer from prefs...
82
83 // If we have no audio, dont even try...
84 ADM_audioStream *s=NULL;
85 if(!video_body->getDefaultAudioTrack(&s)) return NULL;
86 if(!s) return NULL;
87 //
88 ADM_buildFilterChain(trk,&PlaybackVector,&playback);
89 //
90 int last=PlaybackVector.size();
91 ADM_assert(last);
92 return PlaybackVector[last-1];
93 }
94 /**
95 \fn destroyPlaybackFilter
96 \brief Destroy a float output filter for playback
97 */
98
destroyPlaybackFilter(void)99 bool destroyPlaybackFilter(void)
100 {
101
102 ADM_emptyFilterChain(&PlaybackVector);
103 return true;
104
105 }
106 /***********************************************************************/
107 #define ADD_FILTER(x) { vec->push_back(x);last=x;}
108 /**
109 \fn ADM_buildFilterChain
110 \brief Create a filterchain
111 @param vec : VectorFilter to build filters into
112 @param config: Filters configuration
113 */
ADM_buildFilterChain(ADM_edAudioTrack * source,VectorOfAudioFilter * vec,ADM_AUDIOFILTER_CONFIG * config)114 bool ADM_buildFilterChain(ADM_edAudioTrack *source,VectorOfAudioFilter *vec,ADM_AUDIOFILTER_CONFIG *config)
115 {
116 ADM_assert(source);
117 // make sure the chain is empty...
118 AUDMAudioFilter *last=NULL;
119 ADM_emptyFilterChain(vec);
120 // Bridge
121 int32_t actualShift=config->shiftInMs;
122 if(!config->shiftEnabled)
123 actualShift=0;
124 AUDMAudioFilter_Bridge *nw=new AUDMAudioFilter_Bridge(source,(uint32_t)( config->startTimeInUs/1000),actualShift);
125 ADD_FILTER(nw);
126
127 // Mixer
128 if(config->mixerEnabled)
129 {
130 AUDMAudioFilterMixer *mixer=new AUDMAudioFilterMixer(last,config->mixerConf);
131 ADD_FILTER(mixer);
132 }
133 if (config->drcEnabled)
134 {
135 AUDMAudioFilterLimiter *pdrc = NULL;
136 pdrc = new AUDMAudioFilterLimiter(last,&config->drcConf);
137 ADD_FILTER(pdrc);
138 }
139 // Pal 2 film & friends
140 switch(config->film2pal)
141 {
142 case FILMCONV_NONE:
143 break;
144 case FILMCONV_FILM2PAL:
145 {
146 AUDMAudioFilterFilm2Pal *f2p=new AUDMAudioFilterFilm2Pal(last);
147 ADD_FILTER(f2p);
148 }
149 break;
150 case FILMCONV_PAL2FILM:
151 {
152 AUDMAudioFilterPal2Film *f2p=new AUDMAudioFilterPal2Film(last);
153 ADD_FILTER(f2p);
154 }
155 break;
156 default:
157 ADM_assert(0);
158 break;
159
160 }
161 // Resample
162 if(config->resamplerEnabled && config->resamplerFrequency!=last->getInfo()->frequency)
163 {
164 AUDMAudioFilterSrc *src=new AUDMAudioFilterSrc(last,config->resamplerFrequency);
165 ADD_FILTER(src);
166 }
167 // Normalize
168 if(config->gainParam.mode!=ADM_NO_GAIN)
169 {
170 AUDMAudioFilterNormalize *norm=new AUDMAudioFilterNormalize(last,&(config->gainParam));
171 ADD_FILTER(norm);
172 }
173 return true;
174 }
175 /**
176 \fn ADM_emptyFilterChain
177 \brief Destroy a filter chain
178 */
ADM_emptyFilterChain(VectorOfAudioFilter * vec)179 bool ADM_emptyFilterChain(VectorOfAudioFilter *vec)
180 {
181 int nb=vec->size();
182 for(int i=0;i<nb;i++)
183 {
184 delete (*vec)[i];
185 (*vec)[i]=NULL;
186 }
187 vec->clear();
188 return true;
189 }
190 /**
191 * \fn ADM_audioCompareChannelMapping
192 * \brief return true if the two channel mapping are identical, false else.
193 */
ADM_audioCompareChannelMapping(WAVHeader * wh1,WAVHeader * wh2,CHANNEL_TYPE * map1,CHANNEL_TYPE * map2)194 bool ADM_audioCompareChannelMapping(WAVHeader *wh1, WAVHeader *wh2,CHANNEL_TYPE *map1,CHANNEL_TYPE *map2)
195 {
196 if(wh1->channels != wh2->channels) return false; // cannot be identical..
197
198 for (int j = 0; j < wh1->channels; j++)
199 {
200 if (map1[j] != map2[j])
201 {
202 return false;
203
204 }
205 }
206 return true;
207 }
208
209 // EOF
210