headphone.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:17k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * headphone.c : headphone virtual spatialization channel mixer module
  3.  *               -> gives the feeling of a real room with a simple headphone
  4.  *****************************************************************************
  5.  * Copyright (C) 2002 VideoLAN
  6.  * $Id: headphone.c 8845 2004-09-29 09:00:41Z zorglub $
  7.  *
  8.  * Authors: Boris Dor鑣 <babal@via.ecp.fr>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <stdlib.h>                                      /* malloc(), free() */
  28. #include <string.h>
  29. #include <math.h>                                        /* sqrt */
  30. #include <vlc/vlc.h>
  31. #include "audio_output.h"
  32. #include "aout_internal.h"
  33. /*****************************************************************************
  34.  * Local prototypes
  35.  *****************************************************************************/
  36. static int  Create    ( vlc_object_t * );
  37. static void Destroy   ( vlc_object_t * );
  38. static void DoWork    ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
  39.                         aout_buffer_t * );
  40. /*****************************************************************************
  41.  * Module descriptor
  42.  *****************************************************************************/
  43. #define MODULE_DESCRIPTION N_ ( 
  44.      "This effect gives you the feeling that you are standing in a room " 
  45.      "with a complete 5.1 speaker set when using only a headphone, " 
  46.      "providing a more realistic sound experience. It should also be " 
  47.      "more comfortable and less tiring when listening to music for " 
  48.      "long periods of time.nIt works with any source format from mono " 
  49.      "to 5.1.")
  50. #define HEADPHONE_DIM_TEXT N_("Characteristic dimension")
  51. #define HEADPHONE_DIM_LONGTEXT N_( 
  52.      "Distance between front left speaker and listener in meters.")
  53. vlc_module_begin();
  54.     set_description( N_("headphone channel mixer with virtual spatialization effect") );
  55.     add_integer( "headphone-dim", 10, NULL, HEADPHONE_DIM_TEXT,
  56.                  HEADPHONE_DIM_LONGTEXT, VLC_FALSE );
  57.     set_capability( "audio filter", 0 );
  58.     set_callbacks( Create, Destroy );
  59.     add_shortcut( "headphone" );
  60. vlc_module_end();
  61. /*****************************************************************************
  62.  * Internal data structures
  63.  *****************************************************************************/
  64. struct atomic_operation_t
  65. {
  66.     int i_source_channel_offset;
  67.     int i_dest_channel_offset;
  68.     unsigned int i_delay;/* in sample unit */
  69.     double d_amplitude_factor;
  70. };
  71. struct aout_filter_sys_t
  72. {
  73.     size_t i_overflow_buffer_size;/* in bytes */
  74.     byte_t * p_overflow_buffer;
  75.     unsigned int i_nb_atomic_operations;
  76.     struct atomic_operation_t * p_atomic_operations;
  77. };
  78. /*****************************************************************************
  79.  * Init: initialize internal data structures
  80.  * and computes the needed atomic operations
  81.  *****************************************************************************/
  82. /* x and z represent the coordinates of the virtual speaker
  83.  *  relatively to the center of the listener's head, measured in meters :
  84.  *
  85.  *  left              right
  86.  *Z
  87.  *-
  88.  *a          head
  89.  *x
  90.  *i
  91.  *s
  92.  *  rear left    rear right
  93.  *
  94.  *          x-axis
  95.  *  */
  96. static void ComputeChannelOperations ( struct aout_filter_sys_t * p_data
  97.         , unsigned int i_rate , unsigned int i_next_atomic_operation
  98.         , int i_source_channel_offset , double d_x , double d_z
  99.         , double d_channel_amplitude_factor )
  100. {
  101.     double d_c = 340; /*sound celerity (unit: m/s)*/
  102.     /* Left ear */
  103.     p_data->p_atomic_operations[i_next_atomic_operation]
  104.         .i_source_channel_offset = i_source_channel_offset;
  105.     p_data->p_atomic_operations[i_next_atomic_operation]
  106.         .i_dest_channel_offset = 0;/* left */
  107.     p_data->p_atomic_operations[i_next_atomic_operation]
  108.         .i_delay = (int)( sqrt( (-0.1-d_x)*(-0.1-d_x) + (0-d_z)*(0-d_z) )
  109.                           / d_c * i_rate );
  110.     if ( d_x < 0 )
  111.     {
  112.         p_data->p_atomic_operations[i_next_atomic_operation]
  113.             .d_amplitude_factor = d_channel_amplitude_factor * 1.1 / 2;
  114.     }
  115.     else if ( d_x > 0 )
  116.     {
  117.         p_data->p_atomic_operations[i_next_atomic_operation]
  118.             .d_amplitude_factor = d_channel_amplitude_factor * 0.9 / 2;
  119.     }
  120.     else
  121.     {
  122.         p_data->p_atomic_operations[i_next_atomic_operation]
  123.             .d_amplitude_factor = d_channel_amplitude_factor / 2;
  124.     }
  125.     /* Right ear */
  126.     p_data->p_atomic_operations[i_next_atomic_operation + 1]
  127.         .i_source_channel_offset = i_source_channel_offset;
  128.     p_data->p_atomic_operations[i_next_atomic_operation + 1]
  129.         .i_dest_channel_offset = 1;/* right */
  130.     p_data->p_atomic_operations[i_next_atomic_operation + 1]
  131.         .i_delay = (int)( sqrt( (0.1-d_x)*(0.1-d_x) + (0-d_z)*(0-d_z) )
  132.                           / d_c * i_rate );
  133.     if ( d_x < 0 )
  134.     {
  135.         p_data->p_atomic_operations[i_next_atomic_operation + 1]
  136.             .d_amplitude_factor = d_channel_amplitude_factor * 0.9 / 2;
  137.     }
  138.     else if ( d_x > 0 )
  139.     {
  140.         p_data->p_atomic_operations[i_next_atomic_operation + 1]
  141.             .d_amplitude_factor = d_channel_amplitude_factor * 1.1 / 2;
  142.     }
  143.     else
  144.     {
  145.         p_data->p_atomic_operations[i_next_atomic_operation + 1]
  146.             .d_amplitude_factor = d_channel_amplitude_factor / 2;
  147.     }
  148. }
  149. static int Init ( aout_filter_t * p_filter , struct aout_filter_sys_t * p_data
  150.         , unsigned int i_nb_channels , uint32_t i_physical_channels
  151.         , unsigned int i_rate )
  152. {
  153.     double d_x = config_GetInt ( p_filter , "headphone-dim" );
  154.     double d_z = d_x;
  155.     double d_z_rear = -d_x/3;
  156.     unsigned int i_next_atomic_operation;
  157.     int i_source_channel_offset;
  158.     unsigned int i;
  159.     if ( p_data == NULL )
  160.     {
  161.         msg_Dbg ( p_filter, "passing a null pointer as argument" );
  162.         return 0;
  163.     }
  164.     /* Number of elementary operations */
  165.     p_data->i_nb_atomic_operations = i_nb_channels * 2;
  166.     p_data->p_atomic_operations = malloc ( sizeof(struct atomic_operation_t)
  167.             * p_data->i_nb_atomic_operations );
  168.     if ( p_data->p_atomic_operations == NULL )
  169.     {
  170.         msg_Err( p_filter, "out of memory" );
  171.         return -1;
  172.     }
  173.     /* For each virtual speaker, computes elementary wave propagation time
  174.      * to each ear */
  175.     i_next_atomic_operation = 0;
  176.     i_source_channel_offset = 0;
  177.     if ( i_physical_channels & AOUT_CHAN_LEFT )
  178.     {
  179.         ComputeChannelOperations ( p_data , i_rate
  180.                 , i_next_atomic_operation , i_source_channel_offset
  181.                 , -d_x , d_z , 2.0 / i_nb_channels );
  182.         i_next_atomic_operation += 2;
  183.         i_source_channel_offset++;
  184.     }
  185.     if ( i_physical_channels & AOUT_CHAN_RIGHT )
  186.     {
  187.         ComputeChannelOperations ( p_data , i_rate
  188.                 , i_next_atomic_operation , i_source_channel_offset
  189.                 , d_x , d_z , 2.0 / i_nb_channels );
  190.         i_next_atomic_operation += 2;
  191.         i_source_channel_offset++;
  192.     }
  193.     if ( i_physical_channels & AOUT_CHAN_REARLEFT )
  194.     {
  195.         ComputeChannelOperations ( p_data , i_rate
  196.                 , i_next_atomic_operation , i_source_channel_offset
  197.                 , -d_x , d_z_rear , 1.5 / i_nb_channels );
  198.         i_next_atomic_operation += 2;
  199.         i_source_channel_offset++;
  200.     }
  201.     if ( i_physical_channels & AOUT_CHAN_REARRIGHT )
  202.     {
  203.         ComputeChannelOperations ( p_data , i_rate
  204.                 , i_next_atomic_operation , i_source_channel_offset
  205.                 , d_x , d_z_rear , 1.5 / i_nb_channels );
  206.         i_next_atomic_operation += 2;
  207.         i_source_channel_offset++;
  208.     }
  209.     if ( i_physical_channels & AOUT_CHAN_REARCENTER )
  210.     {
  211.         ComputeChannelOperations ( p_data , i_rate
  212.                 , i_next_atomic_operation , i_source_channel_offset
  213.                 , 0 , -d_z , 1.5 / i_nb_channels );
  214.         i_next_atomic_operation += 2;
  215.         i_source_channel_offset++;
  216.     }
  217.     if ( i_physical_channels & AOUT_CHAN_CENTER )
  218.     {
  219.         ComputeChannelOperations ( p_data , i_rate
  220.                 , i_next_atomic_operation , i_source_channel_offset
  221.                 , 0 , d_z , 1.5 / i_nb_channels );
  222.         i_next_atomic_operation += 2;
  223.         i_source_channel_offset++;
  224.     }
  225.     if ( i_physical_channels & AOUT_CHAN_LFE )
  226.     {
  227.         ComputeChannelOperations ( p_data , i_rate
  228.                 , i_next_atomic_operation , i_source_channel_offset
  229.                 , 0 , d_z_rear , 5.0 / i_nb_channels );
  230.         i_next_atomic_operation += 2;
  231.         i_source_channel_offset++;
  232.     }
  233.     if ( i_physical_channels & AOUT_CHAN_MIDDLELEFT )
  234.     {
  235.         ComputeChannelOperations ( p_data , i_rate
  236.                 , i_next_atomic_operation , i_source_channel_offset
  237.                 , -d_x , 0 , 1.5 / i_nb_channels );
  238.         i_next_atomic_operation += 2;
  239.         i_source_channel_offset++;
  240.     }
  241.     if ( i_physical_channels & AOUT_CHAN_MIDDLERIGHT )
  242.     {
  243.         ComputeChannelOperations ( p_data , i_rate
  244.                 , i_next_atomic_operation , i_source_channel_offset
  245.                 , d_x , 0 , 1.5 / i_nb_channels );
  246.         i_next_atomic_operation += 2;
  247.         i_source_channel_offset++;
  248.     }
  249.     /* Initialize the overflow buffer
  250.      * we need it because the process induce a delay in the samples */
  251.     p_data->i_overflow_buffer_size = 0;
  252.     for ( i = 0 ; i < p_data->i_nb_atomic_operations ; i++ )
  253.     {
  254.         if ( p_data->i_overflow_buffer_size
  255.                 < p_data->p_atomic_operations[i].i_delay * i_nb_channels
  256.                 * sizeof (float) )
  257.         {
  258.             p_data->i_overflow_buffer_size
  259.                 = p_data->p_atomic_operations[i].i_delay * i_nb_channels
  260.                 * sizeof (float);
  261.         }
  262.     }
  263.     p_data->p_overflow_buffer = malloc ( p_data->i_overflow_buffer_size );
  264.     if ( p_data->p_atomic_operations == NULL )
  265.     {
  266.         msg_Err( p_filter, "out of memory" );
  267.         return -1;
  268.     }
  269.     memset ( p_data->p_overflow_buffer , 0 , p_data->i_overflow_buffer_size );
  270.     /* end */
  271.     return 0;
  272. }
  273. /*****************************************************************************
  274.  * Create: allocate headphone downmixer
  275.  *****************************************************************************/
  276. static int Create( vlc_object_t *p_this )
  277. {
  278.     aout_filter_t * p_filter = (aout_filter_t *)p_this;
  279.     if ( p_filter->output.i_physical_channels != ( AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT )
  280.           || p_filter->input.i_format != p_filter->output.i_format
  281.           || p_filter->input.i_rate != p_filter->output.i_rate
  282.           || (p_filter->input.i_format != VLC_FOURCC('f','l','3','2')
  283.                && p_filter->input.i_format != VLC_FOURCC('f','i','3','2')) )
  284.     {
  285.         msg_Dbg( p_filter, "Filter discarded (invalid format)" );
  286.         return -1;
  287.     }
  288.     /* Allocate the memory needed to store the module's structure */
  289.     p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) );
  290.     if ( p_filter->p_sys == NULL )
  291.     {
  292.         msg_Err( p_filter, "out of memory" );
  293.         return -1;
  294.     }
  295.     p_filter->p_sys->i_overflow_buffer_size = 0;
  296.     p_filter->p_sys->p_overflow_buffer = NULL;
  297.     p_filter->p_sys->i_nb_atomic_operations = 0;
  298.     p_filter->p_sys->p_atomic_operations = NULL;
  299.     if ( Init( p_filter , p_filter->p_sys
  300.                 , aout_FormatNbChannels ( &p_filter->input )
  301.                 , p_filter->input.i_physical_channels
  302.                 ,  p_filter->input.i_rate ) < 0 )
  303.     {
  304.         return -1;
  305.     }
  306.     p_filter->pf_do_work = DoWork;
  307.     p_filter->b_in_place = 0;
  308.     return 0;
  309. }
  310. /*****************************************************************************
  311.  * Destroy: deallocate resources associated with headphone downmixer
  312.  *****************************************************************************/
  313. static void Destroy( vlc_object_t *p_this )
  314. {
  315.     aout_filter_t * p_filter = (aout_filter_t *)p_this;
  316.     if ( p_filter->p_sys != NULL )
  317.     {
  318.         if ( p_filter->p_sys->p_overflow_buffer != NULL )
  319.         {
  320.             free ( p_filter->p_sys->p_overflow_buffer );
  321.         }
  322.         if ( p_filter->p_sys->p_atomic_operations != NULL )
  323.         {
  324.             free ( p_filter->p_sys->p_atomic_operations );
  325.         }
  326.         free ( p_filter->p_sys );
  327.         p_filter->p_sys = NULL;
  328.     }
  329. }
  330. /*****************************************************************************
  331.  * DoWork: convert a buffer
  332.  *****************************************************************************/
  333. static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
  334.                     aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
  335. {
  336.     int i_input_nb = aout_FormatNbChannels( &p_filter->input );
  337.     int i_output_nb = aout_FormatNbChannels( &p_filter->output );
  338.     float * p_in = (float*) p_in_buf->p_buffer;
  339.     byte_t * p_out;
  340.     byte_t * p_overflow;
  341.     byte_t * p_slide;
  342.     size_t i_overflow_size;/* in bytes */
  343.     size_t i_out_size;/* in bytes */
  344.     unsigned int i, j;
  345.     int i_source_channel_offset;
  346.     int i_dest_channel_offset;
  347.     unsigned int i_delay;
  348.     double d_amplitude_factor;
  349.     /* out buffer characterisitcs */
  350.     p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
  351.     p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * i_output_nb / i_input_nb;
  352.     p_out = p_out_buf->p_buffer;
  353.     i_out_size = p_out_buf->i_nb_bytes;
  354.     if ( p_filter->p_sys != NULL )
  355.     {
  356.         /* Slide the overflow buffer */
  357.         p_overflow = p_filter->p_sys->p_overflow_buffer;
  358.         i_overflow_size = p_filter->p_sys->i_overflow_buffer_size;
  359.         memset ( p_out , 0 , i_out_size );
  360.         if ( i_out_size > i_overflow_size )
  361.             memcpy ( p_out , p_overflow , i_overflow_size );
  362.         else
  363.             memcpy ( p_out , p_overflow , i_out_size );
  364.         p_slide = p_filter->p_sys->p_overflow_buffer;
  365.         while ( p_slide < p_overflow + i_overflow_size )
  366.         {
  367.             if ( p_slide + i_out_size < p_overflow + i_overflow_size )
  368.             {
  369.                 memset ( p_slide , 0 , i_out_size );
  370.                 if ( p_slide + 2 * i_out_size < p_overflow + i_overflow_size )
  371.                     memcpy ( p_slide , p_slide + i_out_size , i_out_size );
  372.                 else
  373.                     memcpy ( p_slide , p_slide + i_out_size
  374.                       , p_overflow + i_overflow_size - ( p_slide + i_out_size ) );
  375.             }
  376.             else
  377.             {
  378.                 memset ( p_slide , 0 , p_overflow + i_overflow_size - p_slide );
  379.             }
  380.             p_slide += i_out_size;
  381.         }
  382.         /* apply the atomic operations */
  383.         for ( i = 0 ; i < p_filter->p_sys->i_nb_atomic_operations ; i++ )
  384.         {
  385.             /* shorter variable names */
  386.             i_source_channel_offset
  387.                 = p_filter->p_sys->p_atomic_operations[i].i_source_channel_offset;
  388.             i_dest_channel_offset
  389.                 = p_filter->p_sys->p_atomic_operations[i].i_dest_channel_offset;
  390.             i_delay = p_filter->p_sys->p_atomic_operations[i].i_delay;
  391.             d_amplitude_factor
  392.                 = p_filter->p_sys->p_atomic_operations[i].d_amplitude_factor;
  393.             if ( p_out_buf->i_nb_samples > i_delay )
  394.             {
  395.                 /* current buffer coefficients */
  396.                 for ( j = 0 ; j < p_out_buf->i_nb_samples - i_delay ; j++ )
  397.                 {
  398.                     ((float*)p_out)[ (i_delay+j)*i_output_nb + i_dest_channel_offset ]
  399.                         += p_in[ j * i_input_nb + i_source_channel_offset ]
  400.                            * d_amplitude_factor;
  401.                 }
  402.                 /* overflow buffer coefficients */
  403.                 for ( j = 0 ; j < i_delay ; j++ )
  404.                 {
  405.                     ((float*)p_overflow)[ j*i_output_nb + i_dest_channel_offset ]
  406.                         += p_in[ (p_out_buf->i_nb_samples - i_delay + j)
  407.                            * i_input_nb + i_source_channel_offset ]
  408.                            * d_amplitude_factor;
  409.                 }
  410.             }
  411.             else
  412.             {
  413.                 /* overflow buffer coefficients only */
  414.                 for ( j = 0 ; j < p_out_buf->i_nb_samples ; j++ )
  415.                 {
  416.                     ((float*)p_overflow)[ (i_delay - p_out_buf->i_nb_samples + j)
  417.                         * i_output_nb + i_dest_channel_offset ]
  418.                         += p_in[ j * i_input_nb + i_source_channel_offset ]
  419.                            * d_amplitude_factor;
  420.                 }
  421.             }
  422.         }
  423.     }
  424.     else
  425.     {
  426.         memset ( p_out , 0 , i_out_size );
  427.     }
  428. }