List of vlc plugins (221)
-$Id: LIST,v 1.10 2003/08/10 12:45:52 zorglub Exp $
+$Id: LIST,v 1.11 2003/08/29 16:56:43 zorglub Exp $
* a52: A/52 basic parser
* downmixsse: SSE accelerated version of downmix.
+ * dshow: DirectShow access plugin for encoding cards under Windows
+
* dts: DTS basic parser
* dtstospdif: Audio converter that encapsulates DTS into S/PDIF
* gnome_main: Gtk+ wrapper for gtk_main
+ * goom: visualisation plugin based on goom
+
* gtk2: interface using the Gtk2 widget set.
* gtk2_main: Gtk+ wrapper for gtk_main
* ncurses: interface module using the ncurses library.
+ * ntservice: run VLC as a NT service
+
* ogg: input module for OGG decapsulation.
* oss: audio output module using the OSS /dev/dsp interface.
* vcd: input module for accessing Video CDs.
+ * visual: visualisation system
+
* vorbis: a vorbis audio decoder using the libvorbis library.
* vout_directx: video output module using the DirectX API.
* x11: video output module using the X11 API.
- * xmga: X11 MGA video_output plugin
-
* xosd: X On Screen Display interface
* xvid: Decoder for the Xvid codec, using libxvidcore
SOURCES_visual = visual.c \
- effects.c
+ effects.c \
+ fft.c
* effects.c : Effects for the visualization system
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: effects.c,v 1.1 2003/08/19 21:20:00 zorglub Exp $
+ * $Id: effects.c,v 1.2 2003/08/29 16:56:43 zorglub Exp $
*
* Authors: Clément Stenac <zorglub@via.ecp.fr>
*
#include "visual.h"
#include <math.h>
+#include "fft.h"
+#define PEAK_SPEED 1
/*****************************************************************************
* Argument list parsers *
*****************************************************************************/
int i_value;
if( psz_parse != NULL )
{
- if(!strncmp( psz_parse, name, strlen(name) ) )
+ while(1)
{
- psz_parse += strlen( name );
- psz_eof = strchr( psz_parse , ',' );
- if( !psz_eof)
- psz_eof = psz_parse + strlen(psz_parse);
- if( psz_eof )
+ if(!strncmp( psz_parse, name, strlen(name) ) )
{
- *psz_eof = '\0' ;
+ psz_parse += strlen( name );
+ psz_eof = strchr( psz_parse , ',' );
+ if( !psz_eof)
+ psz_eof = psz_parse + strlen(psz_parse);
+ if( psz_eof )
+ {
+ *psz_eof = '\0' ;
+ }
+ i_value = atoi(++psz_parse);
+ psz_parse= psz_eof;
+ psz_parse++;
+ return i_value;
}
- i_value = atoi(++psz_parse);
- psz_parse= psz_eof;
- psz_parse++;
- return i_value;
- }
+ if( *psz_parse )
+ psz_parse ++;
+ else
+ break;
+ }
}
return defaut;
}
char *psz_value;
if( psz_parse != NULL )
{
- if(!strncmp( psz_parse, name, strlen(name) ) )
+ while(1)
{
- psz_parse += strlen( name );
- psz_eof = strchr( psz_parse , ',' );
- if( !psz_eof)
- psz_eof = psz_parse + strlen(psz_parse);
- if( psz_eof )
+ if(!strncmp( psz_parse, name, strlen(name) ) )
{
- *psz_eof = '\0' ;
+ psz_parse += strlen( name );
+ psz_eof = strchr( psz_parse , ',' );
+ if( !psz_eof)
+ psz_eof = psz_parse + strlen(psz_parse);
+ if( psz_eof )
+ {
+ *psz_eof = '\0' ;
+ }
+ psz_value = strdup(++psz_parse);
+ psz_parse= psz_eof;
+ psz_parse++;
+ return psz_value;
}
- psz_value = strdup(++psz_parse);
- psz_parse= psz_eof;
- psz_parse++;
- return psz_value;
+ if( *psz_parse )
+ psz_parse ++;
+ else
+ break;
}
}
- return strdup(defaut);
+ return strdup(defaut);
}
int spectrum_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
aout_buffer_t * p_buffer , picture_t * p_picture)
{
- return 0;
+ float p_output[FFT_BUFFER_SIZE]; /* Raw FFT Result */
+ int *height; /* Bar heights */
+ int *peaks; /* Peaks */
+ int i_nb_bands; /* number of bands */
+ int i_band_width; /* width of bands */
+ int i_separ; /* Should we let blanks ? */
+ int i_amp; /* Vertical amplification */
+ int i_peak; /* Should we draw peaks ? */
+ char *psz_parse = NULL; /* Args line */
+
+ /* Horizontal scale for 20-band equalizer */
+ const int xscale1[]={0,1,2,3,4,5,6,7,8,11,15,20,27,
+ 36,47,62,82,107,141,184,255};
+
+ /* Horizontal scale for 80-band equalizer */
+ const int xscale2[] =
+ {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
+ 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
+ 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
+ 52,53,54,55,56,57,58,59,61,63,67,72,77,82,87,93,99,105,
+ 110,115,121,130,141,152,163,174,185,255};
+ const int *xscale;
+ const double y_scale = 3.60673760222; /* (log 256) */
+
+ fft_state *p_state; /* internal FFT data */
+
+ int i , j , y , k;
+ int i_line;
+ s16 p_dest[FFT_BUFFER_SIZE]; /* Adapted FFT result */
+ s16 p_buffer1[FFT_BUFFER_SIZE]; /* Buffer on which we perform
+ the FFT (first channel) */
+
+ float *p_buffl = /* Original buffer */
+ (float*)p_buffer->p_buffer;
+
+ s16 *p_buffs; /* s16 converted buffer */
+ s16 *p_s16_buff = NULL; /* s16 converted buffer */
+
+ p_s16_buff = (s16*)malloc(
+ p_buffer->i_nb_samples * p_effect->i_nb_chans * sizeof(s16));
+
+ if( !p_s16_buff )
+ {
+ msg_Err(p_aout,"Out of memory");
+ return -1;
+ }
+
+ p_buffs = p_s16_buff;
+ if( p_effect->psz_args )
+ {
+ psz_parse = strdup( p_effect->psz_args );
+ i_nb_bands = args_getint ( psz_parse , "nb" , 80 );
+ psz_parse = strdup( p_effect->psz_args );
+ i_separ = args_getint ( psz_parse , "separ", 1 );
+ psz_parse = strdup( p_effect->psz_args );
+ i_amp = args_getint ( psz_parse , "amp", 3 );
+ psz_parse = strdup( p_effect->psz_args );
+ i_peak = args_getint ( psz_parse , "peaks", 1 );
+ }
+ else
+ {
+ i_nb_bands = 80;
+ i_separ = 1;
+ i_amp = 3;
+ i_peak = 1;
+ }
+
+ if( i_nb_bands == 20)
+ {
+ xscale = xscale1;
+ }
+ else
+ {
+ i_nb_bands = 80;
+ xscale = xscale2;
+ }
+
+ if( !p_effect->p_data )
+ {
+ p_effect->p_data=(void *)malloc(i_nb_bands * sizeof(int) );
+ if( !p_effect->p_data)
+ {
+ msg_Err(p_aout,"Out of memory");
+ return -1;
+ }
+ peaks = (int *)p_effect->p_data;
+ for( i = 0 ; i < i_nb_bands ; i++)
+ {
+ peaks[i] = 0;
+ }
+
+ }
+ else
+ {
+ peaks =(int *)p_effect->p_data;
+ }
+
+
+ height = (int *)malloc( i_nb_bands * sizeof(int) );
+ if( !height)
+ {
+ msg_Err(p_aout,"Out of memory");
+ return -1;
+ }
+ /* Convert the buffer to s16 */
+ /* Pasted from float32tos16.c */
+ for (i = p_buffer->i_nb_samples * p_effect->i_nb_chans; i--; )
+ {
+ float f_in = *p_buffl + 384.0;
+ s32 i_in;
+ i_in = *(s32 *)&f_in;
+ if(i_in > 0x43c07fff ) * p_buffs = 32767;
+ else if ( i_in < 0x43bf8000 ) *p_buffs = -32768;
+ else *p_buffs = i_in - 0x43c00000;
+
+ p_buffl++ ; p_buffs++ ;
+ }
+ p_state = fft_init();
+ if( !p_state)
+ {
+ msg_Err(p_aout,"Unable to initialize FFT transform");
+ return -1;
+ }
+ p_buffs = p_s16_buff;
+ for ( i = 0 ; i < FFT_BUFFER_SIZE ; i++)
+ {
+ p_output[i] = 0;
+ p_buffer1[i] = *p_buffs;
+ p_buffs = p_buffs + p_effect->i_nb_chans;
+ }
+ fft_perform( p_buffer1, p_output, p_state);
+ for(i= 0; i< FFT_BUFFER_SIZE ; i++ )
+ p_dest[i] = ( (int) sqrt( p_output [ i + 1 ] ) ) >> 8;
+
+ for ( i = 0 ; i< i_nb_bands ;i++)
+ {
+ /* We search the maximum on one scale */
+ for( j = xscale[i] , y=0 ; j< xscale[ i + 1 ] ; j++ )
+ {
+ if ( p_dest[j] > y )
+ y = p_dest[j];
+ }
+ /* Calculate the height of the bar */
+ y >>=5; /* remove some noise */
+ if( y != 0)
+ {
+ height[i] = (int)log(y)* y_scale;
+ if(height[i] > 150)
+ height[i] = 150;
+ }
+ else
+ {
+ height[i] = 0 ;
+ }
+
+ /* Draw the bar now */
+ i_band_width = floor( p_effect->i_width / i_nb_bands) ;
+
+ if( i_amp * height[i] > peaks[i])
+ {
+ peaks[i] = i_amp * height[i];
+ }
+ else if (peaks[i] > 0 )
+ {
+ peaks[i] -= PEAK_SPEED;
+ if( peaks[i] < i_amp * height[i] )
+ {
+ peaks[i] = i_amp * height[i];
+ }
+ if( peaks[i] < 0 )
+ {
+ peaks[i] = 0;
+ }
+ }
+
+ if( peaks[i] > 0 && i_peak )
+ {
+ if( peaks[i] >= p_effect->i_height )
+ peaks[i] = p_effect->i_height - 2;
+ i_line = peaks[i];
+
+ for( j = 0 ; j< i_band_width - i_separ; j++)
+ {
+ for( k = 0 ; k< 3 ; k ++)
+ {
+ /* Draw the peak */
+ *(p_picture->p[0].p_pixels +
+ (p_picture->p[0].i_lines - i_line -1 -k ) *
+ p_picture->p[0].i_pitch + (i_band_width*i +j) )
+ = 0xff;
+
+ *(p_picture->p[1].p_pixels +
+ (p_picture->p[1].i_lines - i_line /2 -1 -k/2 ) *
+ p_picture->p[1].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) )
+ = 0x00;
+
+ if( 0x04 * (i_line + k ) - 0x0f > 0 )
+ {
+ if ( 0x04 * (i_line + k ) -0x0f < 0xff)
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) )
+ = ( 0x04 * ( i_line + k ) ) -0x0f ;
+ else
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) )
+ = 0xff;
+ }
+ else
+ {
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1 -k/2 ) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) )
+ = 0x10 ;
+ }
+ }
+ }
+ }
+
+ if(height[i] * i_amp > p_effect->i_height)
+ height[i] = floor(p_effect->i_height / i_amp );
+
+ for(i_line = 0 ; i_line < i_amp * height[i]; i_line ++ )
+ {
+ for( j = 0 ; j< i_band_width - i_separ ; j++)
+ {
+ *(p_picture->p[0].p_pixels +
+ (p_picture->p[0].i_lines - i_line -1) *
+ p_picture->p[0].i_pitch + (i_band_width*i +j) ) = 0xff;
+
+ *(p_picture->p[1].p_pixels +
+ (p_picture->p[1].i_lines - i_line /2 -1) *
+ p_picture->p[1].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) ) = 0x00;
+
+
+ if( 0x04 * i_line - 0x0f > 0 )
+ {
+ if( 0x04 * i_line - 0x0f < 0xff )
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) ) =
+ ( 0x04 * i_line) -0x0f ;
+ else
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) ) =
+ 0xff;
+ }
+ else
+ {
+ *(p_picture->p[2].p_pixels +
+ (p_picture->p[2].i_lines - i_line /2 - 1) *
+ p_picture->p[2].i_pitch +
+ ( ( i_band_width * i + j ) /2 ) ) =
+ 0x10 ;
+ }
+ }
+ }
+ }
+
+ fft_close( p_state );
+
+ if( p_s16_buff != NULL )
+ {
+ free( p_s16_buff );
+ p_s16_buff = NULL;
+ }
+
+ if(height) free(height);
+
+ if(psz_parse) free(psz_parse);
+
+ return 0;
}
if( p_effect->psz_args )
{
psz_parse = strdup( p_effect->psz_args );
- while(1)
- {
- i_nb_plots = args_getint ( psz_parse , "nb" , 200 );
- if(i_nb_plots) break;
- if( *psz_parse )
- psz_parse ++;
- else
- break;
- }
+ i_nb_plots = args_getint ( psz_parse , "nb" , 200 );
}
else
{
i_u = rand() % 256;
i_v = rand() % 256;
*(p_picture->p[0].p_pixels + i_position )= i_u;
+ *(p_picture->p[1].p_pixels + i_position/4) = i_v;
+ *(p_picture->p[2].p_pixels + i_position/4) = i_y;
}
return 0;
}
+
+/*****************************************************************************
+ * blur_Run: blur effect
+ *****************************************************************************/
+#if 0
+ /* This code is totally crappy */
+int blur_Run(visual_effect_t * p_effect, aout_instance_t *p_aout,
+ aout_buffer_t * p_buffer , picture_t * p_picture)
+{
+ uint8_t * p_pictures;
+ int i,j;
+ int i_size; /* Total size of one image */
+
+ i_size = (p_picture->p[0].i_pitch * p_picture->p[0].i_lines +
+ p_picture->p[1].i_pitch * p_picture->p[1].i_lines +
+ p_picture->p[2].i_pitch * p_picture->p[2].i_lines );
+
+ if( !p_effect->p_data )
+ {
+ p_effect->p_data=(void *)malloc( 5 * i_size *sizeof(uint8_t));
+
+ if( !p_effect->p_data)
+ {
+ msg_Err(p_aout,"Out of memory");
+ return -1;
+ }
+ p_pictures = (uint8_t *)p_effect->p_data;
+ }
+ else
+ {
+ p_pictures =(uint8_t *)p_effect->p_data;
+ }
+
+ for( i = 0 ; i < 5 ; i++)
+ {
+ for ( j = 0 ; j< p_picture->p[0].i_pitch * p_picture->p[0].i_lines; i++)
+ p_picture->p[0].p_pixels[j] =
+ p_pictures[i * i_size + j] * (100 - 20 * i) /100 ;
+ for ( j = 0 ; j< p_picture->p[1].i_pitch * p_picture->p[1].i_lines; i++)
+ p_picture->p[1].p_pixels[j] =
+ p_pictures[i * i_size +
+ p_picture->p[0].i_pitch * p_picture->p[0].i_lines + j ];
+ for ( j = 0 ; j< p_picture->p[2].i_pitch * p_picture->p[2].i_lines; i++)
+ p_picture->p[2].p_pixels[j] =
+ p_pictures[i * i_size +
+ p_picture->p[0].i_pitch * p_picture->p[0].i_lines +
+ p_picture->p[1].i_pitch * p_picture->p[1].i_lines
+ + j ];
+ }
+
+ memcpy ( &p_pictures[ i_size ] , &p_pictures[0] , 4 * i_size * sizeof(uint8_t) );
+}
+#endif
--- /dev/null
+/*****************************************************************************
+ * fft.c: Iterative implementation of a FFT
+ *****************************************************************************
+ * $Id: fft.c,v 1.1 2003/08/29 16:56:43 zorglub Exp $
+ *
+ * Mainly taken from XMMS's code
+ *
+ * Authors: Richard Boulton <richard@tartarus.org>
+ * Ralph Loader <suckfish@ihug.co.nz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include "fft.h"
+
+#include <stdlib.h>
+#include <math.h>
+#ifndef PI
+ #ifdef M_PI
+ #define PI M_PI
+ #else
+ #define PI 3.14159265358979323846 /* pi */
+ #endif
+#endif
+
+/******************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void fft_prepare(const sound_sample *input, float * re, float * im);
+static void fft_calculate(float * re, float * im);
+static void fft_output(const float *re, const float *im, float *output);
+static int reverseBits(unsigned int initial);
+
+
+/* Table to speed up bit reverse copy */
+static unsigned int bitReverse[FFT_BUFFER_SIZE];
+
+/* The next two tables could be made to use less space in memory, since they
+ * overlap hugely, but hey. */
+static float sintable[FFT_BUFFER_SIZE / 2];
+static float costable[FFT_BUFFER_SIZE / 2];
+
+/*****************************************************************************
+ * These functions are the ones called externally
+ *****************************************************************************/
+
+/*
+ * Initialisation routine - sets up tables and space to work in.
+ * Returns a pointer to internal state, to be used when performing calls.
+ * On error, returns NULL.
+ * The pointer should be freed when it is finished with, by fft_close().
+ */
+fft_state *fft_init(void)
+{
+ fft_state *p_state;
+ unsigned int i;
+
+ p_state = (fft_state *) malloc (sizeof(fft_state));
+ if(! p_state )
+ return NULL;
+
+ for(i = 0; i < FFT_BUFFER_SIZE; i++)
+ {
+ bitReverse[i] = reverseBits(i);
+ }
+ for(i = 0; i < FFT_BUFFER_SIZE / 2; i++)
+ {
+ float j = 2 * PI * i / FFT_BUFFER_SIZE;
+ costable[i] = cos(j);
+ sintable[i] = sin(j);
+ }
+
+ return p_state;
+}
+
+/*
+ * Do all the steps of the FFT, taking as input sound data (as described in
+ * sound.h) and returning the intensities of each frequency as floats in the
+ * range 0 to ((FFT_BUFFER_SIZE / 2) * 32768) ^ 2
+ *
+ * The input array is assumed to have FFT_BUFFER_SIZE elements,
+ * and the output array is assumed to have (FFT_BUFFER_SIZE / 2 + 1) elements.
+ * state is a (non-NULL) pointer returned by fft_init.
+ */
+void fft_perform(const sound_sample *input, float *output, fft_state *state) {
+ /* Convert data from sound format to be ready for FFT */
+ fft_prepare(input, state->real, state->imag);
+
+ /* Do the actual FFT */
+ fft_calculate(state->real, state->imag);
+
+ /* Convert the FFT output into intensities */
+ fft_output(state->real, state->imag, output);
+}
+
+/*
+ * Free the state.
+ */
+void fft_close(fft_state *state) {
+ if(state) free(state);
+}
+
+/*****************************************************************************
+ * These functions are called from the other ones
+ *****************************************************************************/
+
+/*
+ * Prepare data to perform an FFT on
+ */
+static void fft_prepare(const sound_sample *input, float * re, float * im) {
+ unsigned int i;
+ float *p_real = re;
+ float *p_imag = im;
+
+ /* Get input, in reverse bit order */
+ for(i = 0; i < FFT_BUFFER_SIZE; i++)
+ {
+ *p_real++ = input[bitReverse[i]];
+ *p_imag++ = 0;
+ }
+}
+
+/*
+ * Take result of an FFT and calculate the intensities of each frequency
+ * Note: only produces half as many data points as the input had.
+ */
+static void fft_output(const float * re, const float * im, float *output)
+{
+ float *p_output = output;
+ const float *p_real = re;
+ const float *p_imag = im;
+ float *p_end = output + FFT_BUFFER_SIZE / 2;
+
+ while(p_output <= p_end)
+ {
+ *p_output = (*p_real * *p_real) + (*p_imag * *p_imag);
+ p_output++; p_real++; p_imag++;
+ }
+ /* Do divisions to keep the constant and highest frequency terms in scale
+ * with the other terms. */
+ *output /= 4;
+ *p_end /= 4;
+}
+
+
+/*
+ * Actually perform the FFT
+ */
+static void fft_calculate(float * re, float * im)
+{
+ unsigned int i, j, k;
+ unsigned int exchanges;
+ float fact_real, fact_imag;
+ float tmp_real, tmp_imag;
+ unsigned int factfact;
+
+ /* Set up some variables to reduce calculation in the loops */
+ exchanges = 1;
+ factfact = FFT_BUFFER_SIZE / 2;
+
+ /* Loop through the divide and conquer steps */
+ for(i = FFT_BUFFER_SIZE_LOG; i != 0; i--) {
+ /* In this step, we have 2 ^ (i - 1) exchange groups, each with
+ * 2 ^ (FFT_BUFFER_SIZE_LOG - i) exchanges
+ */
+ /* Loop through the exchanges in a group */
+ for(j = 0; j != exchanges; j++) {
+ /* Work out factor for this exchange
+ * factor ^ (exchanges) = -1
+ * So, real = cos(j * PI / exchanges),
+ * imag = sin(j * PI / exchanges)
+ */
+ fact_real = costable[j * factfact];
+ fact_imag = sintable[j * factfact];
+
+ /* Loop through all the exchange groups */
+ for(k = j; k < FFT_BUFFER_SIZE; k += exchanges << 1) {
+ int k1 = k + exchanges;
+ tmp_real = fact_real * re[k1] - fact_imag * im[k1];
+ tmp_imag = fact_real * im[k1] + fact_imag * re[k1];
+ re[k1] = re[k] - tmp_real;
+ im[k1] = im[k] - tmp_imag;
+ re[k] += tmp_real;
+ im[k] += tmp_imag;
+ }
+ }
+ exchanges <<= 1;
+ factfact >>= 1;
+ }
+}
+
+static int reverseBits(unsigned int initial)
+{
+ unsigned int reversed = 0, loop;
+ for(loop = 0; loop < FFT_BUFFER_SIZE_LOG; loop++) {
+ reversed <<= 1;
+ reversed += (initial & 1);
+ initial >>= 1;
+ }
+ return reversed;
+}
--- /dev/null
+/*****************************************************************************
+ * fft.h: Headers for iterative implementation of a FFT
+ *****************************************************************************
+ * $Id: fft.h,v 1.1 2003/08/29 16:56:43 zorglub Exp $
+ *
+ * Mainly taken from XMMS's code
+ *
+ * Authors: Richard Boulton <richard@tartarus.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#ifndef _FFT_H_
+#define _FFT_H_
+
+#define FFT_BUFFER_SIZE_LOG 9
+
+#define FFT_BUFFER_SIZE (1 << FFT_BUFFER_SIZE_LOG)
+
+/* sound sample - should be an signed 16 bit value */
+typedef short int sound_sample;
+
+struct _struct_fft_state {
+ /* Temporary data stores to perform FFT in. */
+ float real[FFT_BUFFER_SIZE];
+ float imag[FFT_BUFFER_SIZE];
+};
+
+/* FFT prototypes */
+typedef struct _struct_fft_state fft_state;
+fft_state *fft_init (void);
+void fft_perform (const sound_sample *input, float *output, fft_state *state);
+void fft_close (fft_state *state);
+
+
+#endif /* _FFT_H_ */
* visual.c : Visualisation system
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: visual.c,v 1.1 2003/08/19 21:20:00 zorglub Exp $
+ * $Id: visual.c,v 1.2 2003/08/29 16:56:43 zorglub Exp $
*
* Authors: Clément Stenac <zorglub@via.ecp.fr>
*
}
p_filter->p_sys->i_height = config_GetInt( p_filter , "effect-height");
- p_filter->p_sys->i_width = config_GetInt( p_filter , "effect-width");
+ p_filter->p_sys->i_width = config_GetInt( p_filter , "effect-width");
+
+ if ( p_filter->p_sys->i_height < 20 )
+ p_filter->p_sys->i_height = 20;
+ if ( p_filter->p_sys->i_width < 20 )
+ p_filter->p_sys->i_width = 20;
+
+ if( (p_filter->p_sys->i_height % 2 ) != 0 )
+ p_filter->p_sys->i_height --;
+
+ if( (p_filter->p_sys->i_width % 2 ) != 0 )
+ p_filter->p_sys->i_width --;
/* Parse the effect list */
psz_effects = config_GetPsz( p_filter, "effect-list" );
p_current_effect = p_filter->p_sys->p_first_effect;
p_current_effect->p_next = NULL;
-
-#define SEARCH(name , function ) \
- if(!strncmp( psz_effects , name, strlen(name) ) ) \
- { \
- p_current_effect->p_next = \
- (visual_effect_t *)malloc( sizeof( visual_effect_t ) ); \
- if( !p_current_effect ) \
- { \
- msg_Err( p_filter, "Out of memory" ); \
- } \
- p_current_effect = p_current_effect -> p_next; \
- p_current_effect->pf_run = NULL; \
- p_current_effect->p_next = NULL; \
- p_current_effect->i_width = p_filter->p_sys->i_width; \
- p_current_effect->i_height = p_filter->p_sys->i_height; \
- p_current_effect->pf_run = function ; \
- p_current_effect->psz_args = NULL; \
- psz_boa = strchr( psz_effects, '{' ); \
- if( psz_boa ) \
- { \
- psz_eoa = strchr( psz_effects, '}'); \
- if( ! psz_eoa ) \
- { \
- msg_Err( p_filter, "Unable to parse effect list. Aborting"); \
- return -1; \
- } \
- *psz_eoa = '\0'; \
- p_current_effect->psz_args = strdup(++psz_boa); \
- psz_effects = psz_eoa; \
- } \
- msg_Dbg(p_filter, "Adding filter: %s ( %s )",name, \
- p_current_effect->psz_args); \
- }
-
while(1)
{
psz_eof = strchr( psz_effects , ';' );
{
*psz_eof = '\0';
}
-
- SEARCH("dummy",dummy_Run);
- SEARCH("scope",scope_Run);
- SEARCH("random",random_Run);
- SEARCH("spectrum",spectrum_Run);
-
+ p_current_effect->p_next =
+ (visual_effect_t *)malloc( sizeof( visual_effect_t ) );
+ if( !p_current_effect )
+ {
+ msg_Err( p_filter, "Out of memory" );
+ }
+ p_current_effect = p_current_effect -> p_next;
+ p_current_effect->pf_run = NULL;
+ p_current_effect->p_next = NULL;
+ p_current_effect->i_width = p_filter->p_sys->i_width;
+ p_current_effect->i_height = p_filter->p_sys->i_height;
+ p_current_effect->p_data = NULL;
+
+ if(! strncasecmp(psz_effects,"dummy",5))
+ p_current_effect->pf_run = dummy_Run;
+ else if(! strncasecmp(psz_effects,"scope",5) )
+ p_current_effect->pf_run = scope_Run;
+ else if(! strncasecmp(psz_effects,"spectrum",8) )
+ p_current_effect->pf_run = spectrum_Run;
+ else if(! strncasecmp(psz_effects,"random",6) )
+ p_current_effect->pf_run = random_Run;
+#if 0
+ else if(! strncasecmp(psz_effects,"blur",4) )
+ p_current_effect->pf_run = blur_Run;
+#endif
+ p_current_effect->psz_args = NULL;
+ p_current_effect->i_nb_chans =
+ aout_FormatNbChannels( &p_filter->input);
+ psz_boa = strchr( psz_effects, '{' );
+ if( psz_boa )
+ {
+ psz_eoa = strchr( psz_effects, '}');
+ if( ! psz_eoa )
+ {
+ msg_Err( p_filter, "Unable to parse effect list. Aborting");
+ return -1;
+ }
+ *psz_eoa = '\0';
+ p_current_effect->psz_args = strdup(++psz_boa);
+ psz_effects = psz_eoa;
+ }
psz_effects = psz_eof;
psz_effects ++;
- if( !* psz_effects || b_end == VLC_TRUE )
+ if( b_end == VLC_TRUE )
break;
}
p_filter->pf_do_work = DoWork;
- p_filter->b_in_place= 0;
+ p_filter->b_in_place= 1;
/* Open the video output */
p_filter->p_sys->p_vout =
- vout_Create( p_filter, p_filter->p_sys->i_width,
+ vout_Request( p_filter, NULL,
+ p_filter->p_sys->i_width,
p_filter->p_sys->i_height,
VLC_FOURCC('I','4','2','0'),
VOUT_ASPECT_FACTOR * p_filter->p_sys->i_width/
while( p_current_effect )
{
+
+#if 1
/* FIXME: Find why it segfaults when we directly call
* p_current_effect->pf_run(....)
* (segfault in errno() ) */
{
spectrum_Run(p_current_effect, p_aout, p_out_buf , p_outpic );
}
-
+#if 0
+ else if (p_current_effect->pf_run == blur_Run )
+ {
+ blur_Run(p_current_effect, p_aout, p_out_buf , p_outpic );
+ }
+#endif
+#else
+ p_current_effect->pf_run(p_current_effect, p_aout, p_out_buf , p_outpic );
+#endif
p_current_effect = p_current_effect->p_next;
}
vout_DisplayPicture ( p_filter->p_sys->p_vout, p_outpic );
-
}
/*****************************************************************************
{
aout_filter_t * p_filter = (aout_filter_t *)p_this;
+ visual_effect_t *p_old;
+ visual_effect_t *p_cur = p_filter->p_sys->p_first_effect;
+
if( p_filter->p_sys->p_vout )
{
vlc_object_detach( p_filter->p_sys->p_vout) ;
vout_Destroy( p_filter->p_sys->p_vout );
}
-
+
+ /* Free the list */
+ while( p_cur )
+ {
+ p_old = p_cur;
+ p_cur = p_cur->p_next;
+ if( p_old ) free( p_old );
+ }
+
if( p_filter->p_sys != NULL )
free( p_filter->p_sys);
}
* visual.h : Header for the visualisation system
*****************************************************************************
* Copyright (C) 2002 VideoLAN
- * $Id: visual.h,v 1.1 2003/08/19 21:20:00 zorglub Exp $
+ * $Id: visual.h,v 1.2 2003/08/29 16:56:43 zorglub Exp $
*
* Authors: Clément Stenac <zorglub@via.ecp.fr>
*
int i_width;
int i_height;
char * psz_args;
+ int i_nb_chans;
} visual_effect_t ;
(visual_effect_t * , aout_instance_t *, aout_buffer_t *, picture_t *);
int spectrum_Run
(visual_effect_t * , aout_instance_t *, aout_buffer_t *, picture_t *);
-
+#if 0
+int blur_Run
+ (visual_effect_t * , aout_instance_t *, aout_buffer_t *, picture_t *);
+#endif
/* Default vout size */
#define VOUT_WIDTH 320