]> git.sesse.net Git - vlc/blob - modules/audio_filter/converter/float.c
Debian's packaging moved
[vlc] / modules / audio_filter / converter / float.c
1 /*****************************************************************************
2  * float.c: Floating point audio format conversions
3  *****************************************************************************
4  * Copyright (C) 2002, 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
8  *          Christophe Massiot <massiot@via.ecp.fr>
9  *          Samuel Hocevar <sam@zoy.org>
10  *          Xavier Maillard <zedek@fxgsproject.org>
11  *          Henri Fallon <henri@videolan.org>
12  *          Gildas Bazin <gbazin@netcourrier.com>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
27  *****************************************************************************/
28
29 /*****************************************************************************
30  * Preamble
31  *****************************************************************************/
32 #include <vlc/vlc.h>
33 #include <stdlib.h>                                      /* malloc(), free() */
34 #include <string.h>
35
36 #ifdef HAVE_UNISTD_H
37 #   include <unistd.h>
38 #endif
39
40 #ifdef HAVE_ALLOCA_H
41 #   include <alloca.h>
42 #endif
43
44 #include <vlc_aout.h>
45
46 /*****************************************************************************
47  * Local prototypes
48  *****************************************************************************/
49 static int  Create_F32ToFL32 ( vlc_object_t * );
50 static void Do_F32ToFL32( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
51                            aout_buffer_t * );
52 static void Do_FL32ToF32 ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
53                            aout_buffer_t * );
54
55 static int  Create_FL32ToS16 ( vlc_object_t * );
56 static void Do_FL32ToS16( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
57                            aout_buffer_t * );
58
59 static int  Create_FL32ToS8 ( vlc_object_t * );
60 static void Do_FL32ToS8( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
61                            aout_buffer_t * );
62
63 static int  Create_FL32ToU16 ( vlc_object_t * );
64 static void Do_FL32ToU16( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
65                            aout_buffer_t * );
66
67 static int  Create_FL32ToU8 ( vlc_object_t * );
68 static void Do_FL32ToU8( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
69                            aout_buffer_t * );
70
71 static int  Create_S16ToFL32( vlc_object_t * );
72 static void Do_S16ToFL32( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
73                            aout_buffer_t * );
74 static void Do_S16ToFL24( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
75                            aout_buffer_t * );
76
77 static int  Create_S16ToFL32_SW( vlc_object_t * );
78 static void Do_S16ToFL32_SW( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
79                            aout_buffer_t * );
80 static void Do_S16ToFL24_SW( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
81                            aout_buffer_t * );
82
83 static int  Create_S8ToFL32( vlc_object_t * );
84 static void Do_S8ToFL32( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
85                            aout_buffer_t * );
86
87 static int  Create_U8ToFL32( vlc_object_t * );
88 static void Do_U8ToFL32( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
89                            aout_buffer_t * );
90
91 /*****************************************************************************
92  * Module descriptor
93  *****************************************************************************/
94 vlc_module_begin();
95     set_description( _("Floating-point audio format conversions") );
96     add_submodule();
97         set_capability( "audio filter", 10 );
98         set_callbacks( Create_F32ToFL32, NULL );
99     add_submodule();
100         set_capability( "audio filter", 1 );
101         set_callbacks( Create_FL32ToS16, NULL );
102     add_submodule();
103         set_capability( "audio filter", 1 );
104         set_callbacks( Create_FL32ToS8, NULL );
105     add_submodule();
106         set_capability( "audio filter", 1 );
107         set_callbacks( Create_FL32ToU16, NULL );
108     add_submodule();
109         set_capability( "audio filter", 1 );
110         set_callbacks( Create_FL32ToU8, NULL );
111     add_submodule();
112         set_capability( "audio filter", 1 );
113         set_callbacks( Create_S16ToFL32, NULL );
114     add_submodule();
115         set_capability( "audio filter", 1 );
116         set_callbacks( Create_S16ToFL32_SW, NULL ); /* Endianness conversion*/
117     add_submodule();
118         set_capability( "audio filter", 1 );
119         set_callbacks( Create_S8ToFL32, NULL );
120     add_submodule();
121         set_capability( "audio filter", 1 );
122         set_callbacks( Create_U8ToFL32, NULL );
123 vlc_module_end();
124
125 /*****************************************************************************
126  * Fixed 32 to Float 32 and backwards
127  *****************************************************************************/
128 static int Create_F32ToFL32( vlc_object_t *p_this )
129 {
130     aout_filter_t * p_filter = (aout_filter_t *)p_this;
131
132     if( ( p_filter->input.i_format != VLC_FOURCC('f','i','3','2')
133            || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
134       && ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
135             || p_filter->output.i_format != VLC_FOURCC('f','i','3','2') ) )
136     {
137         return -1;
138     }
139
140     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
141     {
142         return -1;
143     }
144
145     if( p_filter->input.i_format == VLC_FOURCC('f','i','3','2') )
146     {
147         p_filter->pf_do_work = Do_F32ToFL32;
148     }
149     else
150     {
151         p_filter->pf_do_work = Do_FL32ToF32;
152     }
153
154     p_filter->b_in_place = 1;
155
156     return 0;
157 }
158
159 static void Do_F32ToFL32( aout_instance_t * p_aout, aout_filter_t * p_filter,
160                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
161 {
162     int i;
163     vlc_fixed_t * p_in = (vlc_fixed_t *)p_in_buf->p_buffer;
164     float * p_out = (float *)p_out_buf->p_buffer;
165
166     for ( i = p_in_buf->i_nb_samples
167                * aout_FormatNbChannels( &p_filter->input ) ; i-- ; )
168     {
169         *p_out++ = (float)*p_in++ / (float)FIXED32_ONE;
170     }
171
172     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
173     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes;
174 }
175
176 static void Do_FL32ToF32( aout_instance_t * p_aout, aout_filter_t * p_filter,
177                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
178 {
179     int i;
180     float * p_in = (float *)p_in_buf->p_buffer;
181     vlc_fixed_t * p_out = (vlc_fixed_t *)p_out_buf->p_buffer;
182
183     for ( i = p_in_buf->i_nb_samples
184                * aout_FormatNbChannels( &p_filter->input ) ; i-- ; )
185     {
186         *p_out++ = (vlc_fixed_t)( *p_in++ * (float)FIXED32_ONE );
187     }
188
189     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
190     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes;
191 }
192
193 /*****************************************************************************
194  * FL32 To S16
195  *****************************************************************************/
196 static int Create_FL32ToS16( vlc_object_t *p_this )
197 {
198     aout_filter_t * p_filter = (aout_filter_t *)p_this;
199
200     if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
201           || p_filter->output.i_format != AOUT_FMT_S16_NE )
202     {
203         return -1;
204     }
205
206     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
207     {
208         return -1;
209     }
210
211     p_filter->pf_do_work = Do_FL32ToS16;
212     p_filter->b_in_place = 1;
213
214     return 0;
215 }
216
217 static void Do_FL32ToS16( aout_instance_t * p_aout, aout_filter_t * p_filter,
218                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
219 {
220     int i;
221     float * p_in = (float *)p_in_buf->p_buffer;
222     int16_t * p_out = (int16_t *)p_out_buf->p_buffer;
223
224     for ( i = p_in_buf->i_nb_samples
225                * aout_FormatNbChannels( &p_filter->input ); i-- ; )
226     {
227 #if 0
228         /* Slow version. */
229         if ( *p_in >= 1.0 ) *p_out = 32767;
230         else if ( *p_in < -1.0 ) *p_out = -32768;
231         else *p_out = *p_in * 32768.0;
232 #else
233         /* This is walken's trick based on IEEE float format. */
234         union { float f; int32_t i; } u;
235         u.f = *p_in + 384.0;
236         if ( u.i > 0x43c07fff ) *p_out = 32767;
237         else if ( u.i < 0x43bf8000 ) *p_out = -32768;
238         else *p_out = u.i - 0x43c00000;
239 #endif
240         p_in++; p_out++;
241     }
242
243     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
244     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes / 2;
245 }
246
247 /*****************************************************************************
248  * FL32 To S8
249  *****************************************************************************/
250 static int Create_FL32ToS8( vlc_object_t *p_this )
251 {
252     aout_filter_t * p_filter = (aout_filter_t *)p_this;
253
254     if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
255           || p_filter->output.i_format != VLC_FOURCC('s','8',' ',' ') )
256     {
257         return -1;
258     }
259
260     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
261     {
262         return -1;
263     }
264
265     p_filter->pf_do_work = Do_FL32ToS8;
266     p_filter->b_in_place = 1;
267
268     return 0;
269 }
270
271 static void Do_FL32ToS8( aout_instance_t * p_aout, aout_filter_t * p_filter,
272                          aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
273 {
274     int i;
275     float * p_in = (float *)p_in_buf->p_buffer;
276     int8_t * p_out = (int8_t *)p_out_buf->p_buffer;
277
278     for ( i = p_in_buf->i_nb_samples
279                * aout_FormatNbChannels( &p_filter->input ); i-- ; )
280     {
281         if ( *p_in >= 1.0 ) *p_out = 127;
282         else if ( *p_in < -1.0 ) *p_out = -128;
283         else *p_out = (int8_t)(*p_in * 128);
284         p_in++; p_out++;
285     }
286
287     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
288     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes / 4;
289 }
290
291 /*****************************************************************************
292  * FL32 To U16
293  *****************************************************************************/
294 static int Create_FL32ToU16( vlc_object_t *p_this )
295 {
296     aout_filter_t * p_filter = (aout_filter_t *)p_this;
297
298     if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
299           || p_filter->output.i_format != AOUT_FMT_U16_NE )
300     {
301         return -1;
302     }
303
304     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
305     {
306         return -1;
307     }
308
309     p_filter->pf_do_work = Do_FL32ToU16;
310     p_filter->b_in_place = 1;
311
312     return 0;
313 }
314
315 static void Do_FL32ToU16( aout_instance_t * p_aout, aout_filter_t * p_filter,
316                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
317 {
318     int i;
319     float * p_in = (float *)p_in_buf->p_buffer;
320     uint16_t * p_out = (uint16_t *)p_out_buf->p_buffer;
321
322     for ( i = p_in_buf->i_nb_samples
323                * aout_FormatNbChannels( &p_filter->input ); i-- ; )
324     {
325         if ( *p_in >= 1.0 ) *p_out = 65535;
326         else if ( *p_in < -1.0 ) *p_out = 0;
327         else *p_out = (uint16_t)(32768 + *p_in * 32768);
328         p_in++; p_out++;
329     }
330
331     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
332     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes / 2;
333 }
334
335 /*****************************************************************************
336  * FL32 To U8
337  *****************************************************************************/
338 static int Create_FL32ToU8( vlc_object_t *p_this )
339 {
340     aout_filter_t * p_filter = (aout_filter_t *)p_this;
341
342     if ( p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
343           || p_filter->output.i_format != VLC_FOURCC('u','8',' ',' ') )
344     {
345         return -1;
346     }
347
348     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
349     {
350         return -1;
351     }
352
353     p_filter->pf_do_work = Do_FL32ToU8;
354     p_filter->b_in_place = 1;
355
356     return 0;
357 }
358
359 static void Do_FL32ToU8( aout_instance_t * p_aout, aout_filter_t * p_filter,
360                          aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
361 {
362     int i;
363     float * p_in = (float *)p_in_buf->p_buffer;
364     uint8_t * p_out = (uint8_t *)p_out_buf->p_buffer;
365
366     for ( i = p_in_buf->i_nb_samples
367                * aout_FormatNbChannels( &p_filter->input ); i-- ; )
368     {
369         if ( *p_in >= 1.0 ) *p_out = 255;
370         else if ( *p_in < -1.0 ) *p_out = 0;
371         else *p_out = (uint8_t)(128 + *p_in * 128);
372         p_in++; p_out++;
373     }
374
375     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
376     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes / 4;
377 }
378
379 /*****************************************************************************
380  * S16 To Float32
381  *****************************************************************************/
382 static int Create_S16ToFL32( vlc_object_t *p_this )
383 {
384     aout_filter_t * p_filter = (aout_filter_t *)p_this;
385
386     if ( ( p_filter->input.i_format != AOUT_FMT_S16_NE &&
387            p_filter->input.i_format != AOUT_FMT_S24_NE )
388           || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
389     {
390         return -1;
391     }
392
393     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
394     {
395         return -1;
396     }
397
398     if( p_filter->input.i_format == AOUT_FMT_S24_NE )
399         p_filter->pf_do_work = Do_S16ToFL24;
400     else
401         p_filter->pf_do_work = Do_S16ToFL32;
402
403     p_filter->b_in_place = VLC_TRUE;
404
405     return 0;
406 }
407
408 static void Do_S16ToFL32( aout_instance_t * p_aout, aout_filter_t * p_filter,
409                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
410 {
411     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
412
413     /* We start from the end because b_in_place is true */
414     int16_t * p_in = (int16_t *)p_in_buf->p_buffer + i - 1;
415     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
416
417     while( i-- )
418     {
419 #if 0
420         /* Slow version */
421         *p_out = (float)*p_in / 32768.0;
422 #else
423         /* This is walken's trick based on IEEE float format. On my PIII
424          * this takes 16 seconds to perform one billion conversions, instead
425          * of 19 seconds for the above division. */
426         union { float f; int32_t i; } u;
427         u.i = *p_in + 0x43c00000;
428         *p_out = u.f - 384.0;
429 #endif
430
431         p_in--; p_out--;
432     }
433
434     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
435     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 2;
436 }
437
438 static void Do_S16ToFL24( aout_instance_t * p_aout, aout_filter_t * p_filter,
439                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
440 {
441     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
442
443     /* We start from the end because b_in_place is true */
444     uint8_t * p_in = (uint8_t *)p_in_buf->p_buffer + (i - 1) * 3;
445     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
446
447     while( i-- )
448     {
449 #ifdef WORDS_BIGENDIAN
450         *p_out = ((float)( (((int32_t)*(int16_t *)(p_in)) << 8) + p_in[2]))
451 #else
452         *p_out = ((float)( (((int32_t)*(int16_t *)(p_in+1)) << 8) + p_in[0]))
453 #endif
454             / 8388608.0;
455
456         p_in -= 3; p_out--;
457     }
458
459     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
460     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 4 / 3;
461 }
462
463 /*****************************************************************************
464  * S16 To Float32 with endianness conversion
465  *****************************************************************************/
466 static int Create_S16ToFL32_SW( vlc_object_t *p_this )
467 {
468     aout_filter_t * p_filter = (aout_filter_t *)p_this;
469
470     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
471     {
472         return -1;
473     }
474
475     if ( (p_filter->input.i_format == VLC_FOURCC('s','1','6','l') ||
476          p_filter->input.i_format == VLC_FOURCC('s','1','6','b'))
477          && p_filter->output.i_format == VLC_FOURCC('f','l','3','2')
478          && p_filter->input.i_format != AOUT_FMT_S16_NE )
479     {
480         p_filter->pf_do_work = Do_S16ToFL32_SW;
481         p_filter->b_in_place = VLC_TRUE;
482
483         return 0;
484     }
485
486     if ( (p_filter->input.i_format == VLC_FOURCC('s','2','4','l') ||
487          p_filter->input.i_format == VLC_FOURCC('s','2','4','b'))
488          && p_filter->output.i_format == VLC_FOURCC('f','l','3','2')
489          && p_filter->input.i_format != AOUT_FMT_S24_NE )
490     {
491         p_filter->pf_do_work = Do_S16ToFL24_SW;
492         p_filter->b_in_place = VLC_TRUE;
493
494         return 0;
495     }
496     return -1;
497 }
498
499 static void Do_S16ToFL32_SW( aout_instance_t * p_aout, aout_filter_t * p_filter,
500                           aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
501 {
502     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
503
504     /* We start from the end because b_in_place is true */
505     int16_t * p_in;
506     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
507
508 #ifdef HAVE_SWAB
509 #   ifdef HAVE_ALLOCA
510     int16_t * p_swabbed = alloca( i * sizeof(int16_t) );
511 #   else
512     int16_t * p_swabbed = malloc( i * sizeof(int16_t) );
513 #   endif
514
515     swab( p_in_buf->p_buffer, (void *)p_swabbed, i * sizeof(int16_t) );
516     p_in = p_swabbed + i - 1;
517
518 #else
519     byte_t p_tmp[2];
520     p_in = (int16_t *)p_in_buf->p_buffer + i - 1;
521 #endif
522
523     while( i-- )
524     {
525 #ifndef HAVE_SWAB
526         p_tmp[0] = ((byte_t *)p_in)[1];
527         p_tmp[1] = ((byte_t *)p_in)[0];
528         *p_out = (float)( *(int16_t *)p_tmp ) / 32768.0;
529 #else
530         *p_out = (float)*p_in / 32768.0;
531 #endif
532         p_in--; p_out--;
533     }
534
535 #ifdef HAVE_SWAB
536 #   ifndef HAVE_ALLOCA
537     free( p_swabbed );
538 #   endif
539 #endif
540
541     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
542     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 2;
543 }
544
545 static void Do_S16ToFL24_SW( aout_instance_t * p_aout, aout_filter_t * p_filter,
546                            aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
547 {
548     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
549
550     /* We start from the end because b_in_place is true */
551     uint8_t * p_in = (uint8_t *)p_in_buf->p_buffer + (i - 1) * 3;
552     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
553
554     byte_t p_tmp[3];
555
556     while( i-- )
557     {
558         p_tmp[0] = p_in[2];
559         p_tmp[1] = p_in[1];
560         p_tmp[2] = p_in[0];
561
562 #ifdef WORDS_BIGENDIAN
563         *p_out = ((float)( (((int32_t)*(int16_t *)(p_tmp)) << 8) + p_tmp[2]))
564 #else
565         *p_out = ((float)( (((int32_t)*(int16_t *)(p_tmp+1)) << 8) + p_tmp[0]))
566 #endif
567             / 8388608.0;
568
569         p_in -= 3; p_out--;
570     }
571
572     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
573     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 4 / 3;
574 }
575
576 /*****************************************************************************
577  * S8 To FL32
578  *****************************************************************************/
579 static int Create_S8ToFL32( vlc_object_t *p_this )
580 {
581     aout_filter_t * p_filter = (aout_filter_t *)p_this;
582
583     if ( p_filter->input.i_format != VLC_FOURCC('s','8',' ',' ')
584           || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
585     {
586         return -1;
587     }
588
589     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
590     {
591         return -1;
592     }
593
594     p_filter->pf_do_work = Do_S8ToFL32;
595     p_filter->b_in_place = VLC_TRUE;
596
597     return 0;
598 }
599
600 static void Do_S8ToFL32( aout_instance_t * p_aout, aout_filter_t * p_filter,
601                          aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
602 {
603     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
604
605     /* We start from the end because b_in_place is true */
606     int8_t * p_in = (int8_t *)p_in_buf->p_buffer + i - 1;
607     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
608
609     while( i-- )
610     {
611         *p_out = (float)(*p_in) / 128.0;
612         p_in--; p_out--;
613     }
614
615     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
616     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * sizeof(float);
617 }
618
619 /*****************************************************************************
620  * U8 To FL32
621  *****************************************************************************/
622 static int Create_U8ToFL32( vlc_object_t *p_this )
623 {
624     aout_filter_t * p_filter = (aout_filter_t *)p_this;
625
626     if ( p_filter->input.i_format != VLC_FOURCC('u','8',' ',' ')
627           || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
628     {
629         return -1;
630     }
631
632     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
633     {
634         return -1;
635     }
636
637     p_filter->pf_do_work = Do_U8ToFL32;
638     p_filter->b_in_place = VLC_TRUE;
639
640     return 0;
641 }
642
643 static void Do_U8ToFL32( aout_instance_t * p_aout, aout_filter_t * p_filter,
644                          aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
645 {
646     int i = p_in_buf->i_nb_samples * aout_FormatNbChannels( &p_filter->input );
647
648     /* We start from the end because b_in_place is true */
649     uint8_t * p_in = (uint8_t *)p_in_buf->p_buffer + i - 1;
650     float * p_out = (float *)p_out_buf->p_buffer + i - 1;
651
652     while( i-- )
653     {
654         *p_out = ((float)*p_in -128) / 128.0;
655         p_in--; p_out--;
656     }
657
658     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
659     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * sizeof(float);
660 }