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

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * effects.c : Effects for the visualization system
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 VideoLAN
  5.  * $Id: effects.c 8391 2004-08-06 17:28:36Z sam $
  6.  *
  7.  * Authors: Cl閙ent Stenac <zorglub@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #include <stdlib.h>                                      /* malloc(), free() */
  27. #include <vlc/vlc.h>
  28. #include <vlc/vout.h>
  29. #include "audio_output.h"
  30. #include "aout_internal.h"
  31. #include "visual.h"
  32. #include <math.h>
  33. #include "fft.h"
  34. #define PEAK_SPEED 1
  35. /*****************************************************************************
  36.  * dummy_Run
  37.  *****************************************************************************/
  38. int dummy_Run( visual_effect_t * p_effect, aout_instance_t *p_aout,
  39.                aout_buffer_t * p_buffer , picture_t * p_picture)
  40. {
  41.     return 0;
  42. }
  43. /*****************************************************************************
  44.  * spectrum_Run: spectrum analyser
  45.  *****************************************************************************/
  46. int spectrum_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
  47.                  aout_buffer_t * p_buffer , picture_t * p_picture)
  48. {
  49.     float p_output[FFT_BUFFER_SIZE];  /* Raw FFT Result  */
  50.     int *height;                      /* Bar heights */
  51.     int *peaks;                       /* Peaks */
  52.     int i_nb_bands;                   /* number of bands */
  53.     int i_band_width;                 /* width of bands */
  54.     int i_separ;                      /* Should we let blanks ? */
  55.     int i_amp;                        /* Vertical amplification */
  56.     int i_peak;                       /* Should we draw peaks ? */
  57.     char *psz_parse = NULL;           /* Args line */
  58.     /* Horizontal scale for 20-band equalizer */
  59.     const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
  60.                         36,47,62,82,107,141,184,255};
  61.     /* Horizontal scale for 80-band equalizer */
  62.     const int xscale2[] =
  63.     {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
  64.      19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
  65.      35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
  66.      52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
  67.      110,115,121,130,141,152,163,174,185,200,255};
  68.     const int *xscale;
  69.     const double y_scale =  3.60673760222;  /* (log 256) */
  70.     fft_state *p_state;                 /* internal FFT data */
  71.     int i , j , y , k;
  72.     int i_line;
  73.     int16_t p_dest[FFT_BUFFER_SIZE];      /* Adapted FFT result */
  74.     int16_t p_buffer1[FFT_BUFFER_SIZE];   /* Buffer on which we perform
  75.                                              the FFT (first channel) */
  76.     float *p_buffl =                     /* Original buffer */
  77.             (float*)p_buffer->p_buffer;
  78.     int16_t  *p_buffs;                    /* int16_t converted buffer */
  79.     int16_t  *p_s16_buff = NULL;                /* int16_t converted buffer */
  80.     p_s16_buff = (int16_t*)malloc(
  81.               p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(int16_t));
  82.     if( !p_s16_buff )
  83.     {
  84.         msg_Err(p_aout,"Out of memory");
  85.         return -1;
  86.     }
  87.     p_buffs = p_s16_buff;
  88.     i_nb_bands = config_GetInt ( p_aout, "visual-nbbands" );
  89.     i_separ    = config_GetInt( p_aout, "visual-separ" );
  90.     i_amp     = config_GetInt ( p_aout, "visual-amp" );
  91.     i_peak     = config_GetInt ( p_aout, "visual-peaks" );
  92.     if( i_nb_bands == 20)
  93.     {
  94.         xscale = xscale1;
  95.     }
  96.     else
  97.     {
  98.         i_nb_bands = 80;
  99.         xscale = xscale2;
  100.     }
  101.     if( !p_effect->p_data )
  102.     {
  103.         p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
  104.         if( !p_effect->p_data)
  105.         {
  106.             msg_Err(p_aout,"Out of memory");
  107.             return -1;
  108.         }
  109.         peaks = (int *)p_effect->p_data;
  110.         for( i = 0 ; i < i_nb_bands ; i++)
  111.         {
  112.            peaks[i] = 0;
  113.         }
  114.     }
  115.     else
  116.     {
  117.         peaks =(int *)p_effect->p_data;
  118.     }
  119.     height = (int *)malloc( i_nb_bands * sizeof(int) );
  120.     if( !height)
  121.     {
  122.         msg_Err(p_aout,"Out of memory");
  123.         return -1;
  124.     }
  125.     /* Convert the buffer to int16_t  */
  126.     /* Pasted from float32tos16.c */
  127.     for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
  128.     {
  129.         union { float f; int32_t i; } u;
  130.         u.f = *p_buffl + 384.0;
  131.         if(u.i >  0x43c07fff ) * p_buffs = 32767;
  132.         else if ( u.i < 0x43bf8000 ) *p_buffs = -32768;
  133.         else *p_buffs = u.i - 0x43c00000;
  134.         p_buffl++ ; p_buffs++ ;
  135.     }
  136.     p_state  = visual_fft_init();
  137.     if( !p_state)
  138.     {
  139.         msg_Err(p_aout,"Unable to initialize FFT transform");
  140.         return -1;
  141.     }
  142.     p_buffs = p_s16_buff;
  143.     for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
  144.     {
  145.         p_output[i]    = 0;
  146.         p_buffer1[i] = *p_buffs;
  147.         p_buffs      = p_buffs + p_effect->i_nb_chans;
  148.     }
  149.     fft_perform( p_buffer1, p_output, p_state);
  150.     for(i= 0; i< FFT_BUFFER_SIZE ; i++ )
  151.         p_dest[i] = ( (int) sqrt( p_output [ i + 1 ] ) ) >> 8;
  152.     for ( i = 0 ; i< i_nb_bands ;i++)
  153.     {
  154.         /* We search the maximum on one scale */
  155.         for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ )
  156.         {
  157.             if ( p_dest[j] > y )
  158.                  y = p_dest[j];
  159.         }
  160.         /* Calculate the height of the bar */
  161.         y >>=7;/* remove some noise */
  162.         if( y != 0)
  163.         {
  164.             height[i] = (int)log(y)* y_scale;
  165.                if(height[i] > 150)
  166.                   height[i] = 150;
  167.         }
  168.         else
  169.         {
  170.             height[i] = 0 ;
  171.         }
  172.         /* Draw the bar now */
  173.         i_band_width = floor( p_effect->i_width / i_nb_bands) ;
  174.         if( i_amp * height[i] > peaks[i])
  175.         {
  176.             peaks[i] = i_amp * height[i];
  177.         }
  178.         else if (peaks[i] > 0 )
  179.         {
  180.             peaks[i] -= PEAK_SPEED;
  181.             if( peaks[i] < i_amp * height[i] )
  182.             {
  183.                 peaks[i] = i_amp * height[i];
  184.             }
  185.             if( peaks[i] < 0 )
  186.             {
  187.                 peaks[i] = 0;
  188.             }
  189.         }
  190.         if( peaks[i] > 0 && i_peak )
  191.         {
  192.             if( peaks[i] >= p_effect->i_height )
  193.                 peaks[i] = p_effect->i_height - 2;
  194.             i_line = peaks[i];
  195.             for( j = 0 ; j< i_band_width - i_separ; j++)
  196.             {
  197.                for( k = 0 ; k< 3 ; k ++)
  198.                {
  199.                    /* Draw the peak */
  200.                      *(p_picture->p[0].p_pixels +
  201.                     (p_picture->p[0].i_lines - i_line -1 -k ) *
  202.                      p_picture->p[0].i_pitch + (i_band_width*i +j) )
  203.                                     = 0xff;
  204.                     *(p_picture->p[1].p_pixels +
  205.                      (p_picture->p[1].i_lines - i_line /2 -1 -k/2 ) *
  206.                      p_picture->p[1].i_pitch +
  207.                     ( ( i_band_width * i + j ) /2  ) )
  208.                                     = 0x00;
  209.                    if( 0x04 * (i_line + k ) - 0x0f > 0 )
  210.                    {
  211.                        if ( 0x04 * (i_line + k ) -0x0f < 0xff)
  212.                            *(p_picture->p[2].p_pixels  +
  213.                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
  214.                              p_picture->p[2].i_pitch +
  215.                              ( ( i_band_width * i + j ) /2  ) )
  216.                                     = ( 0x04 * ( i_line + k ) ) -0x0f ;
  217.                        else
  218.                            *(p_picture->p[2].p_pixels  +
  219.                             (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
  220.                              p_picture->p[2].i_pitch +
  221.                              ( ( i_band_width * i + j ) /2  ) )
  222.                                     = 0xff;
  223.                    }
  224.                    else
  225.                    {
  226.                         *(p_picture->p[2].p_pixels  +
  227.                          (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
  228.                          p_picture->p[2].i_pitch +
  229.                          ( ( i_band_width * i + j ) /2  ) )
  230.                                = 0x10 ;
  231.                    }
  232.                }
  233.             }
  234.         }
  235.         if(height[i] * i_amp > p_effect->i_height)
  236.             height[i] = floor(p_effect->i_height / i_amp );
  237.         for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ )
  238.         {
  239.             for( j = 0 ; j< i_band_width - i_separ ; j++)
  240.             {
  241.                *(p_picture->p[0].p_pixels +
  242.                  (p_picture->p[0].i_lines - i_line -1) *
  243.                   p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff;
  244.                 *(p_picture->p[1].p_pixels +
  245.                  (p_picture->p[1].i_lines - i_line /2 -1) *
  246.                  p_picture->p[1].i_pitch +
  247.                  ( ( i_band_width * i + j ) /2  ) ) = 0x00;
  248.                if( 0x04 * i_line - 0x0f > 0 )
  249.                {
  250.                     if( 0x04 * i_line - 0x0f < 0xff )
  251.                          *(p_picture->p[2].p_pixels  +
  252.                           (p_picture->p[2].i_lines - i_line /2 - 1) *
  253.                            p_picture->p[2].i_pitch +
  254.                            ( ( i_band_width * i + j ) /2  ) ) =
  255.                                ( 0x04 * i_line) -0x0f ;
  256.                     else
  257.                          *(p_picture->p[2].p_pixels  +
  258.                           (p_picture->p[2].i_lines - i_line /2 - 1) *
  259.                            p_picture->p[2].i_pitch +
  260.                            ( ( i_band_width * i + j ) /2  ) ) =
  261.                                        0xff;
  262.                }
  263.                else
  264.                {
  265.                     *(p_picture->p[2].p_pixels  +
  266.                      (p_picture->p[2].i_lines - i_line /2 - 1) *
  267.                      p_picture->p[2].i_pitch +
  268.                      ( ( i_band_width * i + j ) /2  ) ) =
  269.                             0x10 ;
  270.                }
  271.             }
  272.         }
  273.     }
  274.     fft_close( p_state );
  275.     if( p_s16_buff != NULL )
  276.     {
  277.         free( p_s16_buff );
  278.         p_s16_buff = NULL;
  279.     }
  280.     if(height) free(height);
  281.     if(psz_parse) free(psz_parse);
  282.     return 0;
  283. }
  284. /*****************************************************************************
  285.  * scope_Run: scope effect
  286.  *****************************************************************************/
  287. int scope_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
  288.               aout_buffer_t * p_buffer , picture_t * p_picture)
  289. {
  290.     int i_index;
  291.     float *p_sample ;
  292.     uint8_t *ppp_area[2][3];
  293.         for( i_index = 0 ; i_index < 2 ; i_index++ )
  294.         {
  295.             int j;
  296.             for( j = 0 ; j < 3 ; j++ )
  297.             {
  298.                 ppp_area[i_index][j] =
  299.                     p_picture->p[j].p_pixels + i_index * p_picture->p[j].i_lines
  300.                                 / 2 * p_picture->p[j].i_pitch;
  301.             }
  302.         }
  303.         for( i_index = 0, p_sample = (float *)p_buffer->p_buffer;
  304.              i_index < p_effect->i_width;
  305.              i_index++ )
  306.         {
  307.             uint8_t i_value;
  308.             /* Left channel */
  309.             i_value =  (*p_sample++ +1) * 127;
  310.             *(ppp_area[0][0]
  311.                + p_picture->p[0].i_pitch * i_index / p_effect->i_width
  312.                + p_picture->p[0].i_lines * i_value / 512
  313.                    * p_picture->p[0].i_pitch) = 0xbf;
  314.             *(ppp_area[0][1]
  315.                 + p_picture->p[1].i_pitch * i_index / p_effect->i_width
  316.                 + p_picture->p[1].i_lines * i_value / 512
  317.                    * p_picture->p[1].i_pitch) = 0xff;
  318.            /* Right channel */
  319.            i_value = ( *p_sample++ +1 ) * 127;
  320.            *(ppp_area[1][0]
  321.               + p_picture->p[0].i_pitch * i_index / p_effect->i_width
  322.               + p_picture->p[0].i_lines * i_value / 512
  323.                  * p_picture->p[0].i_pitch) = 0x9f;
  324.            *(ppp_area[1][2]
  325.               + p_picture->p[2].i_pitch * i_index / p_effect->i_width
  326.               + p_picture->p[2].i_lines * i_value / 512
  327.                 * p_picture->p[2].i_pitch) = 0xdd;
  328.         }
  329.         return 0;
  330. }
  331. /*****************************************************************************
  332.  * random_Run:  random plots display effect
  333.  *****************************************************************************/
  334. int random_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
  335.               aout_buffer_t * p_buffer , picture_t * p_picture)
  336. {
  337.     int i_nb_plots;
  338.     char *psz_parse= NULL;
  339.     int i , i_y , i_u , i_v;
  340.     int i_position;
  341.     srand((unsigned int)mdate());
  342.     if( p_effect->psz_args )
  343.     {
  344.         psz_parse = strdup( p_effect->psz_args );
  345.         i_nb_plots = config_GetInt ( p_aout, "visual-stars" );
  346.     }
  347.     else
  348.     {
  349.         i_nb_plots = 200;
  350.     }
  351.     for( i = 0 ; i < i_nb_plots ; i++ )
  352.     {
  353.         i_position = rand() % (p_effect->i_width * p_effect->i_height );
  354.         i_y = rand() % 256;
  355.         i_u = rand() % 256;
  356.         i_v = rand() % 256;
  357.         *(p_picture->p[0].p_pixels + i_position )= i_u;
  358.         *(p_picture->p[1].p_pixels + i_position/4) = i_v;
  359.         *(p_picture->p[2].p_pixels + i_position/4) = i_y;
  360.     }
  361.     return 0;
  362. }
  363. /*****************************************************************************
  364.  * blur_Run:  blur effect
  365.  *****************************************************************************/
  366. #if 0
  367.   /* This code is totally crappy */
  368. int blur_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
  369.               aout_buffer_t * p_buffer , picture_t * p_picture)
  370. {
  371.     uint8_t * p_pictures;
  372.     int i,j;
  373.     int i_size;   /* Total size of one image */
  374.     i_size = (p_picture->p[0].i_pitch * p_picture->p[0].i_lines +
  375.               p_picture->p[1].i_pitch * p_picture->p[1].i_lines +
  376.               p_picture->p[2].i_pitch * p_picture->p[2].i_lines );
  377.     if( !p_effect->p_data )
  378.     {
  379.         p_effect->p_data=(void *)malloc( 5 * i_size *sizeof(uint8_t));
  380.         if( !p_effect->p_data)
  381.         {
  382.             msg_Err(p_aout,"Out of memory");
  383.             return -1;
  384.         }
  385.         p_pictures = (uint8_t *)p_effect->p_data;
  386.     }
  387.     else
  388.     {
  389.         p_pictures =(uint8_t *)p_effect->p_data;
  390.     }
  391.     for( i = 0 ; i < 5 ; i++)
  392.     {
  393.         for ( j = 0 ; j< p_picture->p[0].i_pitch * p_picture->p[0].i_lines; i++)
  394.             p_picture->p[0].p_pixels[j] =
  395.                     p_pictures[i * i_size + j] * (100 - 20 * i) /100 ;
  396.         for ( j = 0 ; j< p_picture->p[1].i_pitch * p_picture->p[1].i_lines; i++)
  397.             p_picture->p[1].p_pixels[j] =
  398.                     p_pictures[i * i_size +
  399.                     p_picture->p[0].i_pitch * p_picture->p[0].i_lines + j ];
  400.         for ( j = 0 ; j< p_picture->p[2].i_pitch * p_picture->p[2].i_lines; i++)
  401.             p_picture->p[2].p_pixels[j] =
  402.                     p_pictures[i * i_size +
  403.                     p_picture->p[0].i_pitch * p_picture->p[0].i_lines +
  404.                     p_picture->p[1].i_pitch * p_picture->p[1].i_lines
  405.                     + j ];
  406.     }
  407.     memcpy ( &p_pictures[ i_size ] , &p_pictures[0] , 4 * i_size * sizeof(uint8_t) );
  408. }
  409. #endif