| #include "PresetFrameIO.hpp" |
| #include "wipemalloc.h" |
| #include <math.h> |
| #include <cassert> |
| #include <iostream> |
| #include <cmath> |
| #include "Renderer/BeatDetect.hpp" |
| |
| |
| PresetInputs::PresetInputs() : PipelineContext() |
| { |
| } |
| |
| void |
| PresetInputs::update(const BeatDetect & music, const PipelineContext & context) |
| { |
| |
| // Reflect new values form the beat detection unit |
| this->bass = music.bass; |
| this->mid = music.mid; |
| this->treb = music.treb; |
| this->bass_att = music.bass_att; |
| this->mid_att = music.mid_att; |
| this->treb_att = music.treb_att; |
| |
| // Reflect new values from the pipeline context |
| this->fps = context.fps; |
| this->time = context.time; |
| |
| this->frame = context.frame; |
| this->progress = context.progress; |
| } |
| |
| void |
| PresetInputs::Initialize ( int gx, int gy ) |
| { |
| int x, y; |
| |
| this->gx =gx; |
| this->gy= gy; |
| |
| |
| /// @bug no clue if this block belongs here |
| // *** |
| progress = 0; |
| frame = 1; |
| |
| x_per_pixel = 0; |
| y_per_pixel = 0; |
| rad_per_pixel = 0; |
| ang_per_pixel = 0; |
| // *** |
| |
| this->x_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->x_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->y_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x <gx; x++ ) |
| { |
| this->y_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->rad_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->rad_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->theta_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x <gx; x++ ) |
| { |
| this->theta_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| |
| this->origtheta= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->origtheta[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->origrad= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->origrad[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->origx= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->origx[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->origy= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->origy[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| |
| for ( x=0;x<gx;x++ ) |
| { |
| for ( y=0;y<gy;y++ ) |
| { |
| this->origx[x][y]=x/ ( float ) ( gx-1 ); |
| this->origy[x][y]=- ( ( y/ ( float ) ( gy-1 ) )-1 ); |
| this->origrad[x][y]=hypot ( ( this->origx[x][y]-.5 ) *2, ( this->origy[x][y]-.5 ) *2 ) * .7071067; |
| this->origtheta[x][y]=atan2 ( ( ( this->origy[x][y]-.5 ) *2 ), ( ( this->origx[x][y]-.5 ) *2 ) ); |
| } |
| } |
| } |
| |
| PresetOutputs::PresetOutputs() : Pipeline() |
| {} |
| |
| PresetOutputs::~PresetOutputs() |
| { |
| assert(this->gx > 0); |
| |
| for ( int x = 0; x < this->gx; x++ ) |
| { |
| free (this->sx_mesh[x]); |
| free (this->sy_mesh[x]); |
| free (this->dy_mesh[x]); |
| free (this->dx_mesh[x]); |
| free (this->cy_mesh[x]); |
| free (this->cx_mesh[x]); |
| |
| free (this->warp_mesh[x]); |
| free (this->zoom_mesh[x]); |
| free (this->zoomexp_mesh[x]); |
| free (this->rot_mesh[x]); |
| free (this->orig_x[x]); |
| free (this->orig_y[x]); |
| free (this->rad_mesh[x]); |
| } |
| |
| free (this->rad_mesh); |
| free (this->sx_mesh); |
| free (this->sy_mesh); |
| free (this->dy_mesh); |
| free (this->dx_mesh); |
| free (this->cy_mesh); |
| free (this->cx_mesh); |
| free (this->warp_mesh); |
| free (this->zoom_mesh); |
| free (this->zoomexp_mesh); |
| free (this->rot_mesh); |
| free (this->orig_x); |
| free (this->orig_y); |
| |
| } |
| |
| void |
| PresetOutputs::Render(const BeatDetect &music, const PipelineContext &context) |
| { |
| PerPixelMath(context); |
| |
| drawables.clear(); |
| |
| drawables.push_back(&mv); |
| |
| for (PresetOutputs::cshape_container::iterator pos = customShapes.begin(); |
| pos != customShapes.end(); |
| ++pos) |
| { |
| if( (*pos)->enabled==1) drawables.push_back((*pos)); |
| } |
| |
| for (PresetOutputs::cwave_container::iterator pos = customWaves.begin(); |
| pos != customWaves.end(); |
| ++pos) |
| { |
| if( (*pos)->enabled==1) drawables.push_back((*pos)); |
| } |
| |
| drawables.push_back(&wave); |
| if(bDarkenCenter==1) drawables.push_back(&darkenCenter); |
| drawables.push_back(&border); |
| |
| compositeDrawables.clear(); |
| compositeDrawables.push_back(&videoEcho); |
| |
| if (bBrighten==1) |
| compositeDrawables.push_back(&brighten); |
| |
| if (bDarken==1) |
| compositeDrawables.push_back(&darken); |
| |
| if (bSolarize==1) |
| compositeDrawables.push_back(&solarize); |
| |
| if (bInvert==1) |
| compositeDrawables.push_back(&invert); |
| } |
| |
| |
| void |
| PresetOutputs::PerPixelMath(const PipelineContext &context) |
| { |
| int x, y; |
| float fZoom2, fZoom2Inv; |
| |
| for (x = 0; x < gx; x++) |
| { |
| for (y = 0; y < gy; y++) |
| { |
| fZoom2 = std::pow(this->zoom_mesh[x][y], std::pow(this->zoomexp_mesh[x][y], |
| rad_mesh[x][y] * 2.0f - 1.0f)); |
| fZoom2Inv = 1.0f / fZoom2; |
| this->x_mesh[x][y] = this->orig_x[x][y] * 0.5f * fZoom2Inv + 0.5f; |
| this->y_mesh[x][y] = this->orig_y[x][y] * 0.5f * fZoom2Inv + 0.5f; |
| } |
| } |
| |
| for (x = 0; x < gx; x++) |
| { |
| for (y = 0; y < gy; y++) |
| { |
| this->x_mesh[x][y] = (this->x_mesh[x][y] - this->cx_mesh[x][y]) |
| / this->sx_mesh[x][y] + this->cx_mesh[x][y]; |
| } |
| } |
| |
| for (x = 0; x < gx; x++) |
| { |
| for (y = 0; y < gy; y++) |
| { |
| this->y_mesh[x][y] = (this->y_mesh[x][y] - this->cy_mesh[x][y]) |
| / this->sy_mesh[x][y] + this->cy_mesh[x][y]; |
| } |
| } |
| |
| float fWarpTime = context.time * this->fWarpAnimSpeed; |
| float fWarpScaleInv = 1.0f / this->fWarpScale; |
| float f[4]; |
| f[0] = 11.68f + 4.0f * cosf(fWarpTime * 1.413f + 10); |
| f[1] = 8.77f + 3.0f * cosf(fWarpTime * 1.113f + 7); |
| f[2] = 10.54f + 3.0f * cosf(fWarpTime * 1.233f + 3); |
| f[3] = 11.49f + 4.0f * cosf(fWarpTime * 0.933f + 5); |
| |
| for (x = 0; x < gx; x++) |
| { |
| for (y = 0; y < gy; y++) |
| { |
| this->x_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * sinf(fWarpTime * 0.333f |
| + fWarpScaleInv * (this->orig_x[x][y] * f[0] - this->orig_y[x][y] * f[3])); |
| this->y_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * cosf(fWarpTime * 0.375f |
| - fWarpScaleInv * (this->orig_x[x][y] * f[2] + this->orig_y[x][y] * f[1])); |
| this->x_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * cosf(fWarpTime * 0.753f |
| - fWarpScaleInv * (this->orig_x[x][y] * f[1] - this->orig_y[x][y] * f[2])); |
| this->y_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * sinf(fWarpTime * 0.825f |
| + fWarpScaleInv * (this->orig_x[x][y] * f[0] + this->orig_y[x][y] * f[3])); |
| } |
| } |
| for (x = 0; x < gx; x++) |
| { |
| for (y = 0; y < gy; y++) |
| { |
| float u2 = this->x_mesh[x][y] - this->cx_mesh[x][y]; |
| float v2 = this->y_mesh[x][y] - this->cy_mesh[x][y]; |
| |
| float cos_rot = cosf(this->rot_mesh[x][y]); |
| float sin_rot = sinf(this->rot_mesh[x][y]); |
| |
| this->x_mesh[x][y] = u2 * cos_rot - v2 * sin_rot + this->cx_mesh[x][y]; |
| this->y_mesh[x][y] = u2 * sin_rot + v2 * cos_rot + this->cy_mesh[x][y]; |
| } |
| } |
| |
| for (x = 0; x < gx; x++) |
| for (y = 0; y < gy; y++) |
| this->x_mesh[x][y] -= this->dx_mesh[x][y]; |
| |
| for (x = 0; x < gx; x++) |
| for (y = 0; y < gy; y++) |
| this->y_mesh[x][y] -= this->dy_mesh[x][y]; |
| } |
| |
| |
| void |
| PresetOutputs::Initialize ( int gx, int gy ) |
| { |
| assert(gx > 0); |
| this->gx = gx; |
| this->gy= gy; |
| |
| staticPerPixel = true; |
| setStaticPerPixel(gx,gy); |
| |
| assert(this->gx > 0); |
| int x; |
| this->x_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->x_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->y_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->y_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->sx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->sx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->sy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->sy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->dx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->dx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->dy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->dy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->cx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->cx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->cy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->cy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->zoom_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->zoom_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->zoomexp_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->zoomexp_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->rot_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->rot_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| |
| this->warp_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->warp_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->rad_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); |
| for ( x = 0; x < gx; x++ ) |
| { |
| this->rad_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); |
| } |
| this->orig_x = (float **) wipemalloc(gx * sizeof(float *)); |
| for (x = 0; x < gx; x++) |
| { |
| this->orig_x[x] = (float *) wipemalloc(gy * sizeof(float)); |
| } |
| this->orig_y = (float **) wipemalloc(gx * sizeof(float *)); |
| for (x = 0; x < gx; x++) |
| { |
| this->orig_y[x] = (float *) wipemalloc(gy * sizeof(float)); |
| } |
| |
| //initialize reference grid values |
| for (x = 0; x < gx; x++) |
| { |
| for (int y = 0; y < gy; y++) |
| { |
| float origx = x / (float) (gx - 1); |
| float origy = -((y / (float) (gy - 1)) - 1); |
| |
| rad_mesh[x][y]=hypot ( ( origx-.5 ) *2, ( origy-.5 ) *2 ) * .7071067; |
| orig_x[x][y] = (origx - .5) * 2; |
| orig_y[x][y] = (origy - .5) * 2; |
| } |
| } |
| } |
| |
| PresetInputs::~PresetInputs() |
| { |
| for ( int x = 0; x < this->gx; x++ ) |
| { |
| free ( this->origtheta[x] ); |
| free ( this->origrad[x] ); |
| free ( this->origx[x] ); |
| free ( this->origy[x] ); |
| |
| free ( this->x_mesh[x] ); |
| free ( this->y_mesh[x] ); |
| free ( this->rad_mesh[x] ); |
| free ( this->theta_mesh[x] ); |
| } |
| |
| |
| free ( this->origx ); |
| free ( this->origy ); |
| free ( this->origrad ); |
| free ( this->origtheta ); |
| |
| free ( this->x_mesh ); |
| free ( this->y_mesh ); |
| free ( this->rad_mesh ); |
| free ( this->theta_mesh ); |
| |
| this->origx = NULL; |
| this->origy = NULL; |
| this->origtheta = NULL; |
| this->origrad = NULL; |
| |
| this->x_mesh = NULL; |
| this->y_mesh = NULL; |
| this->rad_mesh = NULL; |
| this->theta_mesh = NULL; |
| } |
| |
| |
| void PresetInputs::resetMesh() |
| { |
| int x,y; |
| |
| assert ( x_mesh ); |
| assert ( y_mesh ); |
| assert ( rad_mesh ); |
| assert ( theta_mesh ); |
| |
| for ( x=0;x<this->gx;x++ ) |
| { |
| for ( y=0;y<this->gy;y++ ) |
| { |
| x_mesh[x][y]=this->origx[x][y]; |
| y_mesh[x][y]=this->origy[x][y]; |
| rad_mesh[x][y]=this->origrad[x][y]; |
| theta_mesh[x][y]=this->origtheta[x][y]; |
| } |
| } |
| } |
| |
| |
| #ifdef USE_MERGE_PRESET_CODE |
| void |
| PresetMerger::MergePresets(PresetOutputs & A, PresetOutputs & B, double ratio, int gx, int gy) |
| { |
| |
| double invratio = 1.0 - ratio; |
| //Merge Simple Waveforms |
| // |
| // All the mess is because of Waveform 7, which is two lines. |
| // |
| |
| |
| //Merge Custom Shapes and Custom Waves |
| |
| for (PresetOutputs::cshape_container::iterator pos = A.customShapes.begin(); |
| pos != A.customShapes.end(); |
| ++pos) |
| { |
| (*pos)->a *= invratio; |
| (*pos)->a2 *= invratio; |
| (*pos)->border_a *= invratio; |
| } |
| |
| for (PresetOutputs::cshape_container::iterator pos = B.customShapes.begin(); |
| pos != B.customShapes.end(); |
| ++pos) |
| { |
| (*pos)->a *= ratio; |
| (*pos)->a2 *= ratio; |
| (*pos)->border_a *= ratio; |
| |
| A.customShapes.push_back(*pos); |
| } |
| |
| for (PresetOutputs::cwave_container::iterator pos = A.customWaves.begin(); |
| pos != A.customWaves.end(); |
| ++pos) |
| { |
| (*pos)->a *= invratio; |
| for (int x=0; x < (*pos)->samples; x++) |
| { |
| (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*invratio; |
| } |
| } |
| |
| for (PresetOutputs::cwave_container::iterator pos = B.customWaves.begin(); |
| pos != B.customWaves.end(); |
| ++pos) |
| { |
| (*pos)->a *= ratio; |
| for (int x=0; x < (*pos)->samples; x++) |
| { |
| (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*ratio; |
| } |
| A.customWaves.push_back(*pos); |
| } |
| |
| |
| //Interpolate Per-Pixel mesh |
| |
| for (int x=0;x<gx;x++) |
| { |
| for(int y=0;y<gy;y++) |
| { |
| A.x_mesh[x][y] = A.x_mesh[x][y]* invratio + B.x_mesh[x][y]*ratio; |
| } |
| } |
| for (int x=0;x<gx;x++) |
| { |
| for(int y=0;y<gy;y++) |
| { |
| A.y_mesh[x][y] = A.y_mesh[x][y]* invratio + B.y_mesh[x][y]*ratio; |
| } |
| } |
| |
| |
| |
| //Interpolate PerFrame floats |
| |
| A.screenDecay = A.screenDecay * invratio + B.screenDecay * ratio; |
| |
| A.wave.r = A.wave.r* invratio + B.wave.r*ratio; |
| A.wave.g = A.wave.g* invratio + B.wave.g*ratio; |
| A.wave.b = A.wave.b* invratio + B.wave.b*ratio; |
| A.wave.a = A.wave.a* invratio + B.wave.a*ratio; |
| A.wave.x = A.wave.x* invratio + B.wave.x*ratio; |
| A.wave.y = A.wave.y* invratio + B.wave.y*ratio; |
| A.wave.mystery = A.wave.mystery* invratio + B.wave.mystery*ratio; |
| |
| A.border.outer_size = A.border.outer_size* invratio + B.border.outer_size*ratio; |
| A.border.outer_r = A.border.outer_r* invratio + B.border.outer_r*ratio; |
| A.border.outer_g = A.border.outer_g* invratio + B.border.outer_g*ratio; |
| A.border.outer_b = A.border.outer_b* invratio + B.border.outer_b*ratio; |
| A.border.outer_a = A.border.outer_a* invratio + B.border.outer_a*ratio; |
| |
| A.border.inner_size = A.border.inner_size* invratio + B.border.inner_size*ratio; |
| A.border.inner_r = A.border.inner_r* invratio + B.border.inner_r*ratio; |
| A.border.inner_g = A.border.inner_g* invratio + B.border.inner_g*ratio; |
| A.border.inner_b = A.border.inner_b* invratio + B.border.inner_b*ratio; |
| A.border.inner_a = A.border.inner_a* invratio + B.border.inner_a*ratio; |
| |
| A.mv.a = A.mv.a* invratio + B.mv.a*ratio; |
| A.mv.r = A.mv.r* invratio + B.mv.r*ratio; |
| A.mv.g = A.mv.g* invratio + B.mv.g*ratio; |
| A.mv.b = A.mv.b* invratio + B.mv.b*ratio; |
| A.mv.length = A.mv.length* invratio + B.mv.length*ratio; |
| A.mv.x_num = A.mv.x_num* invratio + B.mv.x_num*ratio; |
| A.mv.y_num = A.mv.y_num* invratio + B.mv.y_num*ratio; |
| A.mv.y_offset = A.mv.y_offset* invratio + B.mv.y_offset*ratio; |
| A.mv.x_offset = A.mv.x_offset* invratio + B.mv.x_offset*ratio; |
| |
| |
| A.fRating = A.fRating* invratio + B.fRating*ratio; |
| A.fGammaAdj = A.fGammaAdj* invratio + B.fGammaAdj*ratio; |
| A.videoEcho.zoom = A.videoEcho.zoom* invratio + B.videoEcho.zoom*ratio; |
| A.videoEcho.a = A.videoEcho.a* invratio + B.videoEcho.a*ratio; |
| |
| |
| A.fWarpAnimSpeed = A.fWarpAnimSpeed* invratio + B.fWarpAnimSpeed*ratio; |
| A.fWarpScale = A.fWarpScale* invratio + B.fWarpScale*ratio; |
| A.fShader = A.fShader* invratio + B.fShader*ratio; |
| |
| //Switch bools and discrete values halfway. Maybe we should do some interesting stuff here. |
| |
| if (ratio > 0.5) |
| { |
| A.videoEcho.orientation = B.videoEcho.orientation; |
| A.textureWrap = B.textureWrap; |
| A.bDarkenCenter = B.bDarkenCenter; |
| A.bRedBlueStereo = B.bRedBlueStereo; |
| A.bBrighten = B.bBrighten; |
| A.bDarken = B.bDarken; |
| A.bSolarize = B.bSolarize; |
| A.bInvert = B.bInvert; |
| A.bMotionVectorsOn = B.bMotionVectorsOn; |
| } |
| |
| return; |
| } |
| #endif |