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