diff options
Diffstat (limited to 'src/post/goom/convolve_fx.c')
-rw-r--r-- | src/post/goom/convolve_fx.c | 398 |
1 files changed, 294 insertions, 104 deletions
diff --git a/src/post/goom/convolve_fx.c b/src/post/goom/convolve_fx.c index 1aaa4ae28..5f7268a7c 100644 --- a/src/post/goom/convolve_fx.c +++ b/src/post/goom/convolve_fx.c @@ -7,139 +7,329 @@ #include <stdlib.h> #include <string.h> -static const char DEF_SCRIPT[] = "\n\n"; -#if 0 -"-> config;\n" -"-> main;\n" -"\n" -"<config>\n" -" float INCREASE_RATE = 150%;\n" -" float DECAY_RATE = 96%;\n" -"\n" -"<main>\n" -" (Sound.Goom_Detection > 0.8) ?\n" -" Bright_Flash.Factor = Bright_Flash.Factor + Sound.Goom_Power * INCREASE_RATE;\n" -"\n" -" Bright_Flash.Factor = Bright_Flash.Factor * DECAY_RATE;\n" -"\n"; -#endif +//#define CONV_MOTIF_W 32 +//#define CONV_MOTIF_WMASK 0x1f + +#define CONV_MOTIF_W 128 +#define CONV_MOTIF_WMASK 0x7f + +typedef char Motif[CONV_MOTIF_W][CONV_MOTIF_W]; + +#include "motif_goom1.h" +#include "motif_goom2.h" + +#define NB_THETA 512 #define MAX 2.0f typedef struct _CONV_DATA{ -/* float factor; - int lock; - int started; - float curPower;*/ - PluginParam light; - PluginParam factor_adj_p; - PluginParam factor_p; - PluginParam script_p; - PluginParam compile_p; - PluginParameters params; - - GoomSL *script; - + PluginParam light; + PluginParam factor_adj_p; + PluginParam factor_p; + PluginParameters params; + + GoomSL *script; + + /* rotozoom */ + int theta; + float ftheta; + int h_sin[NB_THETA]; + int h_cos[NB_THETA]; + int h_height; + float visibility; + Motif conv_motif; + int inverse_motif; + } ConvData; -static void convolve_init(VisualFX *_this) { - ConvData *data; - data = (ConvData*)malloc(sizeof(ConvData)); +/* init rotozoom tables */ +static void compute_tables(VisualFX *_this, PluginInfo *info) +{ + ConvData *data = (ConvData*)_this->fx_data; + double screen_coef; + int i; + double h; + double radian; + + if (data->h_height == info->screen.height) return; - data->light = secure_f_param("Screen Brightness"); - data->light.param.fval.max = 300.0f; - data->light.param.fval.step = 1.0f; - data->light.param.fval.value = 100.0f; + screen_coef = 2.0 * 300.0 / (double)info->screen.height; + data->h_height = info->screen.height; - data->factor_adj_p = secure_f_param("Flash Intensity"); - data->factor_adj_p.param.fval.max = 100.0f; - data->factor_adj_p.param.fval.step = 1.0f; - data->factor_adj_p.param.fval.value = 50.0f; + for ( i=0 ; i<NB_THETA ; i++ ) { + radian = 2*i*M_PI/NB_THETA; + h = (0.2 + cos (radian) / 15.0 * sin(radian * 2.0 + 12.123)) * screen_coef; + data->h_cos[i] = 0x10000 * (-h * cos (radian) * cos(radian)); + data->h_sin[i] = 0x10000 * (h * sin (radian + 1.57) * sin(radian)); + } +} + +static void set_motif(ConvData *data, Motif motif) +{ + int i,j; + for (i=0;i<CONV_MOTIF_W;++i) for (j=0;j<CONV_MOTIF_W;++j) + data->conv_motif[i][j] = motif[CONV_MOTIF_W-i-1][CONV_MOTIF_W-j-1]; +} - data->factor_p = secure_f_feedback("Factor"); -/* FVAL(data->factor_p) = data->factor / MAX;*/ +static void convolve_init(VisualFX *_this, PluginInfo *info) { + ConvData *data; + data = (ConvData*)malloc(sizeof(ConvData)); + _this->fx_data = (void*)data; - data->script_p = secure_s_param("Script"); - set_str_param_value(&data->script_p, DEF_SCRIPT); - data->compile_p = secure_b_param("Compile", 0); + data->light = secure_f_param("Screen Brightness"); + data->light.param.fval.max = 300.0f; + data->light.param.fval.step = 1.0f; + data->light.param.fval.value = 100.0f; - data->params = plugin_parameters ("Bright Flash", 7); - data->params.params[0] = &data->light; - data->params.params[1] = &data->factor_adj_p; - data->params.params[2] = 0; - data->params.params[3] = &data->factor_p; - data->params.params[4] = 0; - data->params.params[5] = &data->script_p; - data->params.params[6] = &data->compile_p; + data->factor_adj_p = secure_f_param("Flash Intensity"); + data->factor_adj_p.param.fval.max = 200.0f; + data->factor_adj_p.param.fval.step = 1.0f; + data->factor_adj_p.param.fval.value = 70.0f; - data->script = gsl_new(); + data->factor_p = secure_f_feedback("Factor"); - _this->params = &data->params; - _this->fx_data = (void*)data; + data->params = plugin_parameters ("Bright Flash", 5); + data->params.params[0] = &data->light; + data->params.params[1] = &data->factor_adj_p; + data->params.params[2] = 0; + data->params.params[3] = &data->factor_p; + data->params.params[4] = 0; + + /* init rotozoom tables */ + compute_tables(_this, info); + data->theta = 0; + data->ftheta = 0.0; + data->visibility = 1.0; + set_motif(data, CONV_MOTIF2); + data->inverse_motif = 0; + + _this->params = &data->params; } static void convolve_free(VisualFX *_this) { - free (_this->fx_data); + free (_this->fx_data); } -void create_output_with_brightness(Pixel *src, Pixel *dest, int screensize, int iff) { - - int i; - - if (iff-256 == 0) { - memcpy(dest,src,screensize*sizeof(Pixel)); - return; - } - for (i=screensize-1;i--;) { - unsigned int f,h,m,n; - - f = (src[i].cop[0] * iff) >> 8; - h = (src[i].cop[1] * iff) >> 8; - m = (src[i].cop[2] * iff) >> 8; - n = (src[i].cop[3] * iff) >> 8; - - dest[i].cop[0] = (f & 0xffffff00) ? 0xff : (unsigned char)f; - dest[i].cop[1] = (h & 0xffffff00) ? 0xff : (unsigned char)h; - dest[i].cop[2] = (m & 0xffffff00) ? 0xff : (unsigned char)m; - dest[i].cop[3] = (n & 0xffffff00) ? 0xff : (unsigned char)n; - } +static void create_output_with_brightness(VisualFX *_this, Pixel *src, Pixel *dest, + PluginInfo *info, int iff) +{ + ConvData *data = (ConvData*)_this->fx_data; + + int x,y; + int i = 0;//info->screen.height * info->screen.width - 1; + + const int c = data->h_cos [data->theta]; + const int s = data->h_sin [data->theta]; + + const int xi = -(info->screen.width/2) * c; + const int yi = (info->screen.width/2) * s; + + const int xj = -(info->screen.height/2) * s; + const int yj = -(info->screen.height/2) * c; + + int xprime = xj; + int yprime = yj; + + int ifftab[16]; + if (data->inverse_motif) { + int i; + for (i=0;i<16;++i) + ifftab[i] = (double)iff * (1.0 + data->visibility * (15.0 - i) / 15.0); + } + else { + int i; + for (i=0;i<16;++i) + ifftab[i] = (double)iff / (1.0 + data->visibility * (15.0 - i) / 15.0); + } + + for (y=info->screen.height;y--;) { + int xtex,ytex; + + xtex = xprime + xi + CONV_MOTIF_W * 0x10000 / 2; + xprime += s; + + ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2; + yprime += c; + +#ifdef HAVE_MMX + __asm__ __volatile__ + ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ + "\n\t movd %[xtex], %%mm2" + "\n\t movd %[ytex], %%mm3" + "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */ + "\n\t movd %[c], %%mm4" + "\n\t movd %[s], %%mm6" + "\n\t pxor %%mm5, %%mm5" + "\n\t psubd %%mm6, %%mm5" + "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */ + "\n\t movd %[motif], %%mm6" /* mm6 = motif */ + + ::[xtex]"g"(xtex) ,[ytex]"g"(ytex) + , [c]"g"(c), [s]"g"(s) + , [motif] "g"(&data->conv_motif[0][0])); + + for (x=info->screen.width;x--;) + { + __asm__ __volatile__ + ( + "\n\t movd %[src], %%mm0" /* mm0 = src */ + "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */ + "\n\t movd %%esi, %%mm5" /* save esi into mm5 */ + "\n\t movq %%mm2, %%mm3" + "\n\t psrld $16, %%mm3" /* mm3 = [ (ytex>>16) | (xtex>>16) ] */ + "\n\t movd %%mm3, %%eax" /* eax = xtex' */ + + "\n\t psrlq $25, %%mm3" + "\n\t movd %%mm3, %%ecx" /* ecx = ytex' << 7 */ + + "\n\t andl $127, %%eax" + "\n\t andl $16256, %%ecx" + + "\n\t addl %%ecx, %%eax" + "\n\t movd %%mm6, %%esi" /* esi = motif */ + "\n\t xorl %%ecx, %%ecx" + "\n\t movb (%%eax,%%esi), %%cl" + + "\n\t movl %[ifftab], %%eax" + "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */ + "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */ + + "\n\t punpcklwd %%mm1, %%mm1" + "\n\t punpcklbw %%mm7, %%mm0" + "\n\t punpckldq %%mm1, %%mm1" + "\n\t psrlw $1, %%mm0" + "\n\t psrlw $2, %%mm1" + "\n\t pmullw %%mm1, %%mm0" + "\n\t psrlw $5, %%mm0" + "\n\t packuswb %%mm7, %%mm0" + "\n\t movd %%mm0, %[dest]" + : [dest] "=g" (dest[i].val) + : [src] "g" (src[i].val) + , [ifftab]"g"(&ifftab[0]) + : "eax","ecx"); + + i++; + } +#else + for (x=info->screen.width;x--;) { + + int iff2; + unsigned int f0,f1,f2,f3; + + xtex += c; + ytex -= s; + + iff2 = ifftab[data->conv_motif[(ytex >>16) & CONV_MOTIF_WMASK][(xtex >> 16) & CONV_MOTIF_WMASK]]; + +#define sat(a) ((a)>0xFF?0xFF:(a)) + f0 = src[i].val; + f1 = ((f0 >> R_OFFSET) & 0xFF) * iff2 >> 8; + f2 = ((f0 >> G_OFFSET) & 0xFF) * iff2 >> 8; + f3 = ((f0 >> B_OFFSET) & 0xFF) * iff2 >> 8; + dest[i].val = (sat(f1) << R_OFFSET) | (sat(f2) << G_OFFSET) | (sat(f3) << B_OFFSET); +/* + f0 = (src[i].cop[0] * iff2) >> 8; + f1 = (src[i].cop[1] * iff2) >> 8; + f2 = (src[i].cop[2] * iff2) >> 8; + f3 = (src[i].cop[3] * iff2) >> 8; + + dest[i].cop[0] = (f0 & 0xffffff00) ? 0xff : (unsigned char)f0; + dest[i].cop[1] = (f1 & 0xffffff00) ? 0xff : (unsigned char)f1; + dest[i].cop[2] = (f2 & 0xffffff00) ? 0xff : (unsigned char)f2; + dest[i].cop[3] = (f3 & 0xffffff00) ? 0xff : (unsigned char)f3; +*/ + i++; + } +#endif + } +#ifdef HAVE_MMX + __asm__ __volatile__ ("\n\t emms"); +#endif + + compute_tables(_this, info); } + +/*#include <stdint.h> + +static uint64_t GetTick() +{ + uint64_t x; + asm volatile ("RDTSC" : "=A" (x)); + return x; +}*/ + + static void convolve_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info) { - ConvData *data = (ConvData*)_this->fx_data; - float ff; - int iff; + ConvData *data = (ConvData*)_this->fx_data; + float ff; + int iff; + + ff = (FVAL(data->factor_p) * FVAL(data->factor_adj_p) + FVAL(data->light) ) / 100.0f; + iff = (unsigned int)(ff * 256); - ff = (FVAL(data->factor_p) * FVAL(data->factor_adj_p) + FVAL(data->light) ) / 100.0f; - iff = (unsigned int)(ff * 256); + { + double fcycle = (double)info->cycle; + double rotate_param, rotate_coef; + float INCREASE_RATE = 1.5; + float DECAY_RATE = 0.955; + if (FVAL(info->sound.last_goom_p) > 0.8) + FVAL(data->factor_p) += FVAL(info->sound.goom_power_p) * INCREASE_RATE; + FVAL(data->factor_p) *= DECAY_RATE; - if (!gsl_is_compiled(data->script)) { -#ifdef VERBOSE - printf("setting default script for dynamic brightness\n"); -#endif - gsl_compile(data->script, DEF_SCRIPT); - } + rotate_param = FVAL(info->sound.last_goom_p); + if (rotate_param < 0.0) + rotate_param = 0.0; + rotate_param += FVAL(info->sound.goom_power_p); - if (BVAL(data->compile_p)) { /* le bouton du pauvre ... */ - gsl_compile(data->script, SVAL(data->script_p)); - BVAL(data->compile_p) = 0; - data->compile_p.change_listener(&data->compile_p); - } + rotate_coef = 4.0 + FVAL(info->sound.goom_power_p) * 6.0; + data->ftheta = (data->ftheta + rotate_coef * sin(rotate_param * 6.3)); + data->theta = ((unsigned int)data->ftheta) % NB_THETA; + data->visibility = (cos(fcycle * 0.001 + 1.5) * sin(fcycle * 0.008) + cos(fcycle * 0.011 + 5.0) - 0.8 + info->sound.speedvar) * 1.5; + if (data->visibility < 0.0) data->visibility = 0.0; + data->factor_p.change_listener(&data->factor_p); + } - if (gsl_is_compiled(data->script)) { - gsl_execute(data->script); + if (data->visibility < 0.01) { + switch (goom_irand(info->gRandom, 300)) + { + case 1: + set_motif(data, CONV_MOTIF1); data->inverse_motif = 1; break; + case 2: + set_motif(data, CONV_MOTIF2); data->inverse_motif = 0; break; } + } - info->methods.create_output_with_brightness(src,dest,info->screen.size,iff); + if ((ff > 0.98f) && (ff < 1.02f)) + memcpy(dest, src, info->screen.size * sizeof(Pixel)); + else + create_output_with_brightness(_this,src,dest,info,iff); +/* +// Benching suite... + { + uint64_t before, after; + double timed; + static double stimed = 10000.0; + before = GetTick(); + data->visibility = 1.0; + create_output_with_brightness(_this,src,dest,info,iff); + after = GetTick(); + timed = (double)((after-before) / info->screen.size); + if (timed < stimed) { + stimed = timed; + printf ("CLK = %3.0f CPP\n", stimed); + } + } +*/ } VisualFX convolve_create(void) { - VisualFX vfx = { - init: convolve_init, - free: convolve_free, - apply: convolve_apply, - fx_data: 0 - }; - return vfx; + VisualFX vfx = { + init: convolve_init, + free: convolve_free, + apply: convolve_apply, + fx_data: 0 + }; + return vfx; } |