float.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:23k
源码类别:

midi

开发平台:

Unix_Linux

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