]> git.sesse.net Git - mlt/blob - src/modules/core/filter_audioconvert.c
Fix manual deinterlace on B in composite.
[mlt] / src / modules / core / filter_audioconvert.c
1 /*
2  * filter_audioconvert.c -- convert from one audio format to another
3  * Copyright (C) 2009 Ushodaya Enterprises Limited
4  * Author: Dan Dennedy <dan@dennedy.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <framework/mlt_filter.h>
22 #include <framework/mlt_frame.h>
23 #include <framework/mlt_log.h>
24
25 #include <stdio.h>
26 #include <stdlib.h>
27
28 static int convert_audio( mlt_frame frame, void **audio, mlt_audio_format *format, mlt_audio_format requested_format )
29 {
30         int error = 1;
31         mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
32         int channels = mlt_properties_get_int( properties, "audio_channels" );
33         int samples = mlt_properties_get_int( properties, "audio_samples" );
34         int size = mlt_audio_format_size( requested_format, samples, channels );
35
36         if ( *format != requested_format )
37         {
38                 mlt_log_debug( NULL, "[filter audioconvert] %s -> %s %d channels %d samples\n",
39                         mlt_audio_format_name( *format ), mlt_audio_format_name( requested_format ),
40                         channels, samples );
41                 switch ( *format )
42                 {
43                 case mlt_audio_s16:
44                         switch ( requested_format )
45                         {
46                         case mlt_audio_s32:
47                         {
48                                 int32_t *buffer = mlt_pool_alloc( size );
49                                 int32_t *p = buffer;
50                                 int c;
51                                 for ( c = 0; c < channels; c++ )
52                                 {
53                                         int16_t *q = (int16_t*) *audio + c;
54                                         int i = samples + 1;
55                                         while ( --i )
56                                         {
57                                                 *p++ = (int32_t) *q << 16;
58                                                 q += channels;
59                                         }
60                                 }
61                                 *audio = buffer;
62                                 error = 0;
63                                 break;
64                         }
65                         case mlt_audio_float:
66                         {
67                                 float *buffer = mlt_pool_alloc( size );
68                                 float *p = buffer;
69                                 int c;
70                                 for ( c = 0; c < channels; c++ )
71                                 {
72                                         int16_t *q = (int16_t*) *audio + c;
73                                         int i = samples + 1;
74                                         while ( --i )
75                                         {
76                                                 *p++ = (float)( *q ) / 32768.0;
77                                                 q += channels;
78                                         }
79                                 }
80                                 *audio = buffer;
81                                 error = 0;
82                                 break;
83                         }
84                         default:
85                                 break;
86                         }
87                         break;
88                 case mlt_audio_s32:
89                         switch ( requested_format )
90                         {
91                         case mlt_audio_s16:
92                         {
93                                 int16_t *buffer = mlt_pool_alloc( size );
94                                 int16_t *p = buffer;
95                                 int32_t *q = (int32_t*) *audio;
96                                 int s, c;
97                                 for ( s = 0; s < samples; s++ )
98                                         for ( c = 0; c < channels; c++ )
99                                                 *p++ = *( q + c * samples + s ) >> 16;
100                                 *audio = buffer;
101                                 error = 0;
102                                 break;
103                         }
104                         case mlt_audio_float:
105                         {
106                                 float *buffer = mlt_pool_alloc( size );
107                                 float *p = buffer;
108                                 int32_t *q = (int32_t*) *audio;
109                                 int i = samples * channels + 1;
110                                 while ( --i )
111                                         *p++ = (float)( *q++ ) / 2147483648.0;
112                                 *audio = buffer;
113                                 error = 0;
114                                 break;
115                         }
116                         default:
117                                 break;
118                         }
119                         break;
120                 case mlt_audio_float:
121                         switch ( requested_format )
122                         {
123                         case mlt_audio_s16:
124                         {
125                                 int16_t *buffer = mlt_pool_alloc( size );
126                                 int16_t *p = buffer;
127                                 float *q = (float*) *audio;
128                                 int s, c;
129                                 for ( s = 0; s < samples; s++ )
130                                         for ( c = 0; c < channels; c++ )
131                                         {
132                                                 float f = *( q + c * samples + s );
133                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
134                                                 *p++ = 32767 * f;
135                                         }
136                                 *audio = buffer;
137                                 error = 0;
138                                 break;
139                         }
140                         case mlt_audio_s32:
141                         {
142                                 int32_t *buffer = mlt_pool_alloc( size );
143                                 int32_t *p = buffer;
144                                 float *q = (float*) *audio;
145                                 int i = samples * channels + 1;
146                                 while ( --i )
147                                 {
148                                         float f = *q++;
149                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
150                                         *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
151                                 }
152                                 *audio = buffer;
153                                 error = 0;
154                                 break;
155                         }
156                         default:
157                                 break;
158                         }
159                         break;
160                 case mlt_audio_s32le:
161                         switch ( requested_format )
162                         {
163                         case mlt_audio_s16:
164                         {
165                                 int16_t *buffer = mlt_pool_alloc( size );
166                                 int16_t *p = buffer;
167                                 int32_t *q = (int32_t*) *audio;
168                                 int i = samples * channels + 1;
169                                 while ( --i )
170                                         *p++ = *q++ >> 16;
171                                 *audio = buffer;
172                                 error = 0;
173                                 break;
174                         }
175                         case mlt_audio_s32:
176                         {
177                                 int32_t *buffer = mlt_pool_alloc( size );
178                                 int32_t *p = buffer;
179                                 int c;
180                                 for ( c = 0; c < channels; c++ )
181                                 {
182                                         int32_t *q = (int32_t*) *audio + c;
183                                         int i = samples + 1;
184                                         while ( --i )
185                                         {
186                                                 *p++ = *q;
187                                                 q += channels;
188                                         }
189                                 }
190                                 *audio = buffer;
191                                 error = 0;
192                                 break;
193                         }
194                         case mlt_audio_float:
195                         {
196                                 float *buffer = mlt_pool_alloc( size );
197                                 float *p = buffer;
198                                 int c;
199                                 for ( c = 0; c < channels; c++ )
200                                 {
201                                         int32_t *q = (int32_t*) *audio + c;
202                                         int i = samples + 1;
203                                         while ( --i )
204                                         {
205                                                 *p++ = (float)( *q ) / 2147483648.0;
206                                                 q += channels;
207                                         }
208                                 }
209                                 *audio = buffer;
210                                 error = 0;
211                                 break;
212                         }
213                         default:
214                                 break;
215                         }
216                         break;
217                 case mlt_audio_f32le:
218                         switch ( requested_format )
219                         {
220                         case mlt_audio_s16:
221                         {
222                                 int16_t *buffer = mlt_pool_alloc( size );
223                                 int16_t *p = buffer;
224                                 float *q = (float*) *audio;
225                                 int i = samples * channels + 1;
226                                 while ( --i )
227                                 {
228                                         float f = *q++;
229                                         f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
230                                         *p++ = 32767 * f;
231                                 }
232                                 *audio = buffer;
233                                 error = 0;
234                                 break;
235                         }
236                         case mlt_audio_float:
237                         {
238                                 float *buffer = mlt_pool_alloc( size );
239                                 float *p = buffer;
240                                 int c;
241                                 for ( c = 0; c < channels; c++ )
242                                 {
243                                         float *q = (float*) *audio + c;
244                                         int i = samples + 1;
245                                         while ( --i )
246                                         {
247                                                 *p++ = *q;
248                                                 q += channels;
249                                         }
250                                 }
251                                 *audio = buffer;
252                                 error = 0;
253                                 break;
254                         }
255                         case mlt_audio_s32:
256                         {
257                                 int32_t *buffer = mlt_pool_alloc( size );
258                                 int32_t *p = buffer;
259                                 int c;
260                                 for ( c = 0; c < channels; c++ )
261                                 {
262                                         float *q = (float*) *audio + c;
263                                         int i = samples + 1;
264                                         while ( --i )
265                                         {
266                                                 float f = *q;
267                                                 f = f > 1.0 ? 1.0 : f < -1.0 ? -1.0 : f;
268                                                 *p++ = ( f > 0 ? 2147483647LL : 2147483648LL ) * f;
269                                                 q += channels;
270                                         }
271                                 }
272                                 *audio = buffer;
273                                 error = 0;
274                                 break;
275                         }
276                         default:
277                                 break;
278                         }
279                         break;
280                 default:
281                         break;
282                 }
283         }
284         if ( !error )
285         {
286                 mlt_frame_set_audio( frame, *audio, requested_format, size, mlt_pool_release );
287                 *format = requested_format;
288         }
289         return error;
290 }
291
292 /** Filter processing.
293 */
294
295 static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
296 {
297         frame->convert_audio = convert_audio;
298         return frame;
299 }
300
301 /** Constructor for the filter.
302 */
303
304 mlt_filter filter_audioconvert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
305 {
306         mlt_filter this = calloc( sizeof( struct mlt_filter_s ), 1 );
307         if ( mlt_filter_init( this, this ) == 0 )
308                 this->process = filter_process;
309         return this;
310 }