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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mpgatofixed32.c: MPEG-1 & 2 audio layer I, II, III + MPEG 2.5 decoder,
  3.  * using MAD (MPEG Audio Decoder)
  4.  *****************************************************************************
  5.  * Copyright (C) 2001-2005 the VideoLAN team
  6.  * $Id: 357ccb8b6c88cab7bd1dff3f5e83e2c6c58171cb $
  7.  *
  8.  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  9.  *          Jean-Paul Saman <jpsaman _at_ videolan _dot_ org>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*****************************************************************************
  26.  * Preamble
  27.  *****************************************************************************/
  28. #include <mad.h>
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_plugin.h>
  34. #include <vlc_aout.h>
  35. #include <vlc_block.h>
  36. #include "vlc_filter.h"
  37. /*****************************************************************************
  38.  * Local prototypes
  39.  *****************************************************************************/
  40. static int  Create    ( vlc_object_t * );
  41. static void Destroy   ( vlc_object_t * );
  42. static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
  43.                         aout_buffer_t * );
  44. static int  OpenFilter ( vlc_object_t * );
  45. static void CloseFilter( vlc_object_t * );
  46. static block_t *Convert( filter_t *, block_t * );
  47. /*****************************************************************************
  48.  * Local structures
  49.  *****************************************************************************/
  50. struct filter_sys_t
  51. {
  52.     struct mad_stream mad_stream;
  53.     struct mad_frame  mad_frame;
  54.     struct mad_synth  mad_synth;
  55.     int               i_reject_count;
  56. };
  57. /*****************************************************************************
  58.  * Module descriptor
  59.  *****************************************************************************/
  60. vlc_module_begin ()
  61.     set_category( CAT_INPUT )
  62.     set_subcategory( SUBCAT_INPUT_ACODEC )
  63.     set_description( N_("MPEG audio decoder") )
  64.     set_capability( "audio filter", 100 )
  65.     set_callbacks( Create, Destroy )
  66.     add_submodule ()
  67.     set_description( N_("MPEG audio decoder") )
  68.     set_capability( "audio filter2", 100 )
  69.     set_callbacks( OpenFilter, CloseFilter )
  70. vlc_module_end ()
  71. /*****************************************************************************
  72.  * Create:
  73.  *****************************************************************************/
  74. static int Create( vlc_object_t *p_this )
  75. {
  76.     aout_filter_t *p_filter = (aout_filter_t *)p_this;
  77.     struct filter_sys_t *p_sys;
  78.     if ( (p_filter->input.i_format != VLC_FOURCC('m','p','g','a')
  79.            && p_filter->input.i_format != VLC_FOURCC('m','p','g','3'))
  80.             || (p_filter->output.i_format != VLC_FOURCC('f','l','3','2')
  81.                  && p_filter->output.i_format != VLC_FOURCC('f','i','3','2')) )
  82.     {
  83.         return -1;
  84.     }
  85.     if ( !AOUT_FMTS_SIMILAR( &p_filter->input, &p_filter->output ) )
  86.     {
  87.         return -1;
  88.     }
  89.     /* Allocate the memory needed to store the module's structure */
  90.     p_sys = malloc( sizeof(filter_sys_t) );
  91.     p_filter->p_sys = (struct aout_filter_sys_t *)p_sys;
  92.     if( p_sys == NULL )
  93.         return -1;
  94.     /* Initialize libmad */
  95.     mad_stream_init( &p_sys->mad_stream );
  96.     mad_frame_init( &p_sys->mad_frame );
  97.     mad_synth_init( &p_sys->mad_synth );
  98.     mad_stream_options( &p_sys->mad_stream, MAD_OPTION_IGNORECRC );
  99.     p_sys->i_reject_count = 0;
  100.     p_filter->pf_do_work = DoWork;
  101.     p_filter->b_in_place = 0;
  102.     return 0;
  103. }
  104. /*****************************************************************************
  105.  * DoWork: decode an MPEG audio frame.
  106.  *****************************************************************************/
  107. static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
  108.                     aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
  109. {
  110.     filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
  111.     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
  112.     p_out_buf->i_nb_bytes = p_in_buf->i_nb_samples * sizeof(vlc_fixed_t) *
  113.                                aout_FormatNbChannels( &p_filter->output );
  114.     /* Do the actual decoding now. */
  115.     mad_stream_buffer( &p_sys->mad_stream, p_in_buf->p_buffer,
  116.                        p_in_buf->i_nb_bytes );
  117.     if ( mad_frame_decode( &p_sys->mad_frame, &p_sys->mad_stream ) == -1 )
  118.     {
  119.         msg_Dbg( p_aout, "libmad error: %s",
  120.                   mad_stream_errorstr( &p_sys->mad_stream ) );
  121.         p_sys->i_reject_count = 3;
  122.     }
  123.     else if( p_in_buf->b_discontinuity )
  124.     {
  125.         p_sys->i_reject_count = 3;
  126.     }
  127.     if( p_sys->i_reject_count > 0 )
  128.     {
  129.         if( p_filter->output.i_format == VLC_FOURCC('f','l','3','2') )
  130.         {
  131.             int i;
  132.             int i_size = p_out_buf->i_nb_bytes / sizeof(float);
  133.             float * a = (float *)p_out_buf->p_buffer;
  134.             for ( i = 0 ; i < i_size ; i++ )
  135.                 *a++ = 0.0;
  136.         }
  137.         else
  138.         {
  139.             memset( p_out_buf->p_buffer, 0, p_out_buf->i_nb_bytes );
  140.         }
  141.         p_sys->i_reject_count--;
  142.         return;
  143.     }
  144.     mad_synth_frame( &p_sys->mad_synth, &p_sys->mad_frame );
  145.     if ( p_filter->output.i_format == VLC_FOURCC('f','i','3','2') )
  146.     {
  147.         /* Interleave and keep buffers in mad_fixed_t format */
  148.         mad_fixed_t * p_samples = (mad_fixed_t *)p_out_buf->p_buffer;
  149.         struct mad_pcm * p_pcm = &p_sys->mad_synth.pcm;
  150.         unsigned int i_samples = p_pcm->length;
  151.         mad_fixed_t const * p_left = p_pcm->samples[0];
  152.         mad_fixed_t const * p_right = p_pcm->samples[1];
  153.         switch ( p_pcm->channels )
  154.         {
  155.         case 2:
  156.             if ( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER )
  157.             {
  158.                 while ( i_samples-- )
  159.                 {
  160.                     *p_samples++ = (*p_left++ >> 1) + (*p_right++ >> 1);
  161.                 }
  162.             }
  163.             else if ( p_filter->output.i_original_channels == AOUT_CHAN_LEFT )
  164.             {
  165.                 while ( i_samples-- )
  166.                 {
  167.                     *p_samples++ = *p_left;
  168.                     *p_samples++ = *p_left++;
  169.                 }
  170.             }
  171.             else if ( p_filter->output.i_original_channels == AOUT_CHAN_RIGHT )
  172.             {
  173.                 while ( i_samples-- )
  174.                 {
  175.                     *p_samples++ = *p_right;
  176.                     *p_samples++ = *p_right++;
  177.                 }
  178.             }
  179.             else
  180.             {
  181.                 while ( i_samples-- )
  182.                 {
  183.                     *p_samples++ = *p_left++;
  184.                     *p_samples++ = *p_right++;
  185.                 }
  186.             }
  187.             break;
  188.         case 1:
  189.             vlc_memcpy( p_samples, p_left, i_samples * sizeof(mad_fixed_t) );
  190.             break;
  191.         default:
  192.             msg_Err( p_aout, "cannot interleave %i channels",
  193.                      p_pcm->channels );
  194.         }
  195.     }
  196.     else
  197.     {
  198.         /* float32 */
  199.         float * p_samples = (float *)p_out_buf->p_buffer;
  200.         struct mad_pcm * p_pcm = &p_sys->mad_synth.pcm;
  201.         unsigned int i_samples = p_pcm->length;
  202.         mad_fixed_t const * p_left = p_pcm->samples[0];
  203.         mad_fixed_t const * p_right = p_pcm->samples[1];
  204.         float f_temp = (float)FIXED32_ONE;
  205.         switch ( p_pcm->channels )
  206.         {
  207.         case 2:
  208.             if ( p_filter->output.i_physical_channels == AOUT_CHAN_CENTER )
  209.             {
  210.                 while ( i_samples-- )
  211.                 {
  212.                     *p_samples++ = (float)*p_left++ / f_temp / 2 +
  213.                                    (float)*p_right++ / f_temp / 2;
  214.                 }
  215.             }
  216.             else if ( p_filter->output.i_original_channels == AOUT_CHAN_LEFT )
  217.             {
  218.                 while ( i_samples-- )
  219.                 {
  220.                     *p_samples++ = (float)*p_left / f_temp;
  221.                     *p_samples++ = (float)*p_left++ / f_temp;
  222.                 }
  223.             }
  224.             else if ( p_filter->output.i_original_channels == AOUT_CHAN_RIGHT )
  225.             {
  226.                 while ( i_samples-- )
  227.                 {
  228.                     *p_samples++ = (float)*p_right / f_temp;
  229.                     *p_samples++ = (float)*p_right++ / f_temp;
  230.                 }
  231.             }
  232.             else
  233.             {
  234.                 while ( i_samples-- )
  235.                 {
  236.                     *p_samples++ = (float)*p_left++ / f_temp;
  237.                     *p_samples++ = (float)*p_right++ / f_temp;
  238.                 }
  239.             }
  240.             break;
  241.         case 1:
  242.             while ( i_samples-- )
  243.             {
  244.                 *p_samples++ = (float)*p_left++ / f_temp;
  245.             }
  246.             break;
  247.         default:
  248.             msg_Err( p_aout, "cannot interleave %i channels",
  249.                      p_pcm->channels );
  250.         }
  251.     }
  252. }
  253. /*****************************************************************************
  254.  * Destroy : deallocate data structures
  255.  *****************************************************************************/
  256. static void Destroy( vlc_object_t *p_this )
  257. {
  258.     aout_filter_t *p_filter = (aout_filter_t *)p_this;
  259.     filter_sys_t *p_sys = (filter_sys_t *)p_filter->p_sys;
  260.     mad_synth_finish( &p_sys->mad_synth );
  261.     mad_frame_finish( &p_sys->mad_frame );
  262.     mad_stream_finish( &p_sys->mad_stream );
  263.     free( p_sys );
  264. }
  265. /*****************************************************************************
  266.  * OpenFilter:
  267.  *****************************************************************************/
  268. static int OpenFilter( vlc_object_t *p_this )
  269. {
  270.     filter_t *p_filter = (filter_t *)p_this;
  271.     filter_sys_t *p_sys;
  272.     if( p_filter->fmt_in.i_codec != VLC_FOURCC('m','p','g','a') &&
  273.         p_filter->fmt_in.i_codec != VLC_FOURCC('m','p','g','3') )
  274.     {
  275.         return VLC_EGENERIC;
  276.     }
  277.     /* Allocate the memory needed to store the module's structure */
  278.     p_sys = p_filter->p_sys = malloc( sizeof(filter_sys_t) );
  279.     if( p_sys == NULL )
  280.         return -1;
  281.     p_sys->i_reject_count = 0;
  282.     p_filter->pf_audio_filter = Convert;
  283.     /* Initialize libmad */
  284.     mad_stream_init( &p_sys->mad_stream );
  285.     mad_frame_init( &p_sys->mad_frame );
  286.     mad_synth_init( &p_sys->mad_synth );
  287.     mad_stream_options( &p_sys->mad_stream, MAD_OPTION_IGNORECRC );
  288.     if( vlc_CPU() & CPU_CAPABILITY_FPU )
  289.         p_filter->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
  290.     else
  291.         p_filter->fmt_out.i_codec = VLC_FOURCC('f','i','3','2');
  292.     p_filter->fmt_out.audio.i_format = p_filter->fmt_out.i_codec;
  293.     p_filter->fmt_out.audio.i_bitspersample =
  294.         aout_BitsPerSample( p_filter->fmt_out.i_codec );
  295.     p_filter->fmt_out.audio.i_rate = p_filter->fmt_in.audio.i_rate;
  296.     msg_Dbg( p_this, "%4.4s->%4.4s, bits per sample: %i",
  297.              (char *)&p_filter->fmt_in.i_codec,
  298.              (char *)&p_filter->fmt_out.i_codec,
  299.              p_filter->fmt_in.audio.i_bitspersample );
  300.     return 0;
  301. }
  302. /*****************************************************************************
  303.  * CloseFilter : deallocate data structures
  304.  *****************************************************************************/
  305. static void CloseFilter( vlc_object_t *p_this )
  306. {
  307.     filter_t *p_filter = (filter_t *)p_this;
  308.     filter_sys_t *p_sys = p_filter->p_sys;
  309.     mad_synth_finish( &p_sys->mad_synth );
  310.     mad_frame_finish( &p_sys->mad_frame );
  311.     mad_stream_finish( &p_sys->mad_stream );
  312.     free( p_sys );
  313. }
  314. static block_t *Convert( filter_t *p_filter, block_t *p_block )
  315. {
  316.     aout_filter_t aout_filter;
  317.     aout_buffer_t in_buf, out_buf;
  318.     block_t *p_out;
  319.     int i_out_size;
  320.     if( !p_block || !p_block->i_samples )
  321.     {
  322.         if( p_block )
  323.             block_Release( p_block );
  324.         return NULL;
  325.     }
  326.     i_out_size = p_block->i_samples *
  327.       p_filter->fmt_out.audio.i_bitspersample *
  328.         p_filter->fmt_out.audio.i_channels / 8;
  329.     p_out = p_filter->pf_audio_buffer_new( p_filter, i_out_size );
  330.     if( !p_out )
  331.     {
  332.         msg_Warn( p_filter, "can't get output buffer" );
  333.         block_Release( p_block );
  334.         return NULL;
  335.     }
  336.     p_out->i_samples = p_block->i_samples;
  337.     p_out->i_dts = p_block->i_dts;
  338.     p_out->i_pts = p_block->i_pts;
  339.     p_out->i_length = p_block->i_length;
  340.     aout_filter.p_sys = (struct aout_filter_sys_t *)p_filter->p_sys;
  341.     aout_filter.input = p_filter->fmt_in.audio;
  342.     aout_filter.input.i_format = p_filter->fmt_in.i_codec;
  343.     aout_filter.output = p_filter->fmt_out.audio;
  344.     aout_filter.output.i_format = p_filter->fmt_out.i_codec;
  345.     in_buf.p_buffer = p_block->p_buffer;
  346.     in_buf.b_discontinuity = false;
  347.     in_buf.i_nb_bytes = p_block->i_buffer;
  348.     in_buf.i_nb_samples = p_block->i_samples;
  349.     out_buf.p_buffer = p_out->p_buffer;
  350.     out_buf.i_nb_bytes = p_out->i_buffer;
  351.     out_buf.i_nb_samples = p_out->i_samples;
  352.     DoWork( (aout_instance_t *)p_filter, &aout_filter, &in_buf, &out_buf );
  353.     block_Release( p_block );
  354.     p_out->i_buffer = out_buf.i_nb_bytes;
  355.     p_out->i_samples = out_buf.i_nb_samples;
  356.     return p_out;
  357. }