From 31fd2c5cd90f1b5addfc0820da3df9379b9c99d2 Mon Sep 17 00:00:00 2001 From: psperl Date: Sun, 12 Aug 2007 18:28:48 +0000 Subject: [PATCH] Smooth Preset Switching. Simple waveforms not animated properly. I think something is amiss with shapes git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/personal/carm/dev-1.0@321 6778bc44-b910-0410-a7a0-be141de4315d --- src/projectM-engine/InitCond.cpp | 4 +- src/projectM-engine/Preset.hpp | 4 +- src/projectM-engine/PresetFrameIO.cpp | 11 +- src/projectM-engine/PresetFrameIO.hpp | 3 + src/projectM-engine/PresetMerge.cpp | 76 ++++++-------- src/projectM-engine/PresetMerge.hpp | 1 - src/projectM-engine/Renderer.cpp | 67 ++++++++----- src/projectM-engine/Renderer.hpp | 3 +- src/projectM-engine/console_interface.cpp | 3 + src/projectM-engine/projectM.cpp | 117 +++++++++++++++------- src/projectM-engine/projectM.hpp | 4 + 11 files changed, 179 insertions(+), 114 deletions(-) diff --git a/src/projectM-engine/InitCond.cpp b/src/projectM-engine/InitCond.cpp index 1cb3aa03c..5102c6c54 100755 --- a/src/projectM-engine/InitCond.cpp +++ b/src/projectM-engine/InitCond.cpp @@ -43,7 +43,7 @@ int InitCond::init_cond_string_buffer_index = 0; InitCond::InitCond( Param * _param, CValue _init_val ):param(_param), init_val(_init_val) { - std::cerr << "InitCond::InitCond: " << this->param->name << std::endl; + // std::cerr << "InitCond::InitCond: " << this->param->name << std::endl; assert(param); assert(param->engine_val); @@ -67,7 +67,7 @@ void InitCond::evaluate() { param->matrix_flag = 0; if (param->type == P_TYPE_BOOL) { - printf( "init_cond: %s = %d (TYPE BOOL)\n", param->name.c_str(), init_val.bool_val); + // printf( "init_cond: %s = %d (TYPE BOOL)\n", param->name.c_str(), init_val.bool_val); assert(param->engine_val); diff --git a/src/projectM-engine/Preset.hpp b/src/projectM-engine/Preset.hpp index 975f2d7c6..331e9e7c3 100644 --- a/src/projectM-engine/Preset.hpp +++ b/src/projectM-engine/Preset.hpp @@ -59,7 +59,7 @@ protected: public: - + PresetOutputs & m_presetOutputs; /// Load a preset by filename with input and output buffers specified. /// This is the only proper way to allocate a new preset. /// \param filename the absolute file path of a preset to load from the file system @@ -143,7 +143,7 @@ private: void initialize(const std::string & pathname); void loadUnspecInitConds(); - PresetOutputs & m_presetOutputs; + }; template diff --git a/src/projectM-engine/PresetFrameIO.cpp b/src/projectM-engine/PresetFrameIO.cpp index 742639ad4..eb2c19e08 100644 --- a/src/projectM-engine/PresetFrameIO.cpp +++ b/src/projectM-engine/PresetFrameIO.cpp @@ -15,7 +15,6 @@ void PresetInputs::Initialize ( int gx, int gy ) this->gy=gy; std::cerr << "Allocating x_mesh, gx,gy is " << gx << "," << gy << std::endl; this->x_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) ); - assert ( x_mesh ); for ( x = 0; x < gx; x++ ) { this->x_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) ); @@ -79,6 +78,16 @@ void PresetOutputs::Initialize ( int gx, int gy ) { 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++ ) { diff --git a/src/projectM-engine/PresetFrameIO.hpp b/src/projectM-engine/PresetFrameIO.hpp index 969845404..49a97e5d5 100644 --- a/src/projectM-engine/PresetFrameIO.hpp +++ b/src/projectM-engine/PresetFrameIO.hpp @@ -133,6 +133,9 @@ public: bool cx_is_mesh; bool cy_is_mesh; + float **x_mesh; + float **y_mesh; + }; diff --git a/src/projectM-engine/PresetMerge.cpp b/src/projectM-engine/PresetMerge.cpp index c0c4e0e1b..d7ccdd5c0 100644 --- a/src/projectM-engine/PresetMerge.cpp +++ b/src/projectM-engine/PresetMerge.cpp @@ -19,25 +19,48 @@ void PresetMerger::MergePresets(PresetOutputs & A, PresetOutputs & B, double rat pos->second->a *= invratio; pos->second->a2 *= invratio; pos->second->border_a *= invratio; - A.customShapes[pos->first>>4]=pos->second; + A.customShapes[pos->first>>8]=pos->second; } for (PresetOutputs::cwave_container::iterator pos = A.customWaves.begin(); pos != A.customWaves.end(); ++pos) { - pos->second->a *= ratio; + pos->second->a *= ratio; + for (int x; x < pos->second->samples; x++) + { + pos->second->a_mesh[x]=pos->second->a_mesh[x]*ratio; + } } for (PresetOutputs::cwave_container::iterator pos = B.customWaves.begin(); pos != B.customWaves.end(); ++pos) { - pos->second->a *= invratio; - A.customWaves[pos->first>>4]=pos->second; - + pos->second->a *= invratio; + for (int x; x < pos->second->samples; x++) + { + pos->second->a_mesh[x]=pos->second->a_mesh[x]*invratio; + } + A.customWaves[pos->first>>8]=pos->second; } + for (int x=0;xpresetName = "None"; + this->gx=gx; this->gy=gy; @@ -135,7 +137,7 @@ void Renderer::RenderFrame(PresetOutputs *presetOutputs, PresetInputs *presetInp DWRITE( "renderFrame: renderTarget->texsize: %d x %d\n", this->renderTarget->texsize, this->renderTarget->texsize ); - PerPixelMath(presetOutputs, presetInputs); + //PerPixelMath(presetOutputs, presetInputs); if(this->renderTarget->usePbuffers) { @@ -245,9 +247,9 @@ void Renderer::Interpolation(PresetOutputs *presetOutputs, PresetInputs *presetI for (int x=0;xgx - 1;x++){ glBegin(GL_TRIANGLE_STRIP); for(int y=0;ygy;y++){ - glTexCoord2f(presetInputs->x_mesh[x][y], presetInputs->y_mesh[x][y]); + glTexCoord2f(presetOutputs->x_mesh[x][y], presetOutputs->y_mesh[x][y]); glVertex2f(this->gridx[x][y], this->gridy[x][y]); - glTexCoord2f(presetInputs->x_mesh[x+1][y], presetInputs->y_mesh[x+1][y]); + glTexCoord2f(presetOutputs->x_mesh[x+1][y], presetOutputs->y_mesh[x+1][y]); glVertex2f(this->gridx[x+1][y], this->gridy[x+1][y]); } glEnd(); @@ -307,8 +309,8 @@ void Renderer::PerFrame(PresetOutputs *presetOutputs) glTranslatef((-presetOutputs->cx) ,(-presetOutputs->cy),0); */ - if(!presetOutputs->dx_is_mesh) glTranslatef(-presetOutputs->dx,0,0); - if(!presetOutputs->dy_is_mesh) glTranslatef(0 ,-presetOutputs->dy,0); + //if(!presetOutputs->dx_is_mesh) glTranslatef(-presetOutputs->dx,0,0); + //if(!presetOutputs->dy_is_mesh) glTranslatef(0 ,-presetOutputs->dy,0); } @@ -342,7 +344,7 @@ Renderer::~Renderer() { } -void Renderer::PerPixelMath(PresetOutputs *presetOutputs, PresetInputs *presetInputs) { +void Renderer::PerPixelMath(PresetOutputs * presetOutputs, PresetInputs * presetInputs) { int x,y; float fZoom2,fZoom2Inv; @@ -383,6 +385,21 @@ void Renderer::PerPixelMath(PresetOutputs *presetOutputs, PresetInputs *presetIn presetOutputs->sy_mesh[x][y]=presetOutputs->sy; }} } + if(!presetOutputs->dx_is_mesh) + { + for (x=0;xgx;x++){ + for(y=0;ygy;y++){ + presetOutputs->dx_mesh[x][y]=presetOutputs->dx; + }} + } + + if(!presetOutputs->dy_is_mesh) + { + for (x=0;xgx;x++){ + for(y=0;ygy;y++){ + presetOutputs->dy_mesh[x][y]=presetOutputs->dy; + }} + } if(!presetOutputs->zoom_is_mesh) { @@ -428,56 +445,54 @@ void Renderer::PerPixelMath(PresetOutputs *presetOutputs, PresetInputs *presetIn for(y=0;ygy;y++){ fZoom2 = powf( presetOutputs->zoom_mesh[x][y], powf( presetOutputs->zoomexp_mesh[x][y], presetInputs->rad_mesh[x][y]*2.0f - 1.0f)); fZoom2Inv = 1.0f/fZoom2; - presetInputs->x_mesh[x][y]= this->origx2[x][y]*0.5f*fZoom2Inv + 0.5f; - presetInputs->y_mesh[x][y]= this->origy2[x][y]*0.5f*fZoom2Inv + 0.5f; + presetOutputs->x_mesh[x][y]= this->origx2[x][y]*0.5f*fZoom2Inv + 0.5f; + presetOutputs->y_mesh[x][y]= this->origy2[x][y]*0.5f*fZoom2Inv + 0.5f; } } for (x=0;xgx;x++){ for(y=0;ygy;y++){ - presetInputs->x_mesh[x][y] = ( presetInputs->x_mesh[x][y] - presetOutputs->cx_mesh[x][y])/presetOutputs->sx_mesh[x][y] + presetOutputs->cx_mesh[x][y]; + presetOutputs->x_mesh[x][y] = ( presetOutputs->x_mesh[x][y] - presetOutputs->cx_mesh[x][y])/presetOutputs->sx_mesh[x][y] + presetOutputs->cx_mesh[x][y]; } } for (x=0;xgx;x++){ for(y=0;ygy;y++){ - presetInputs->y_mesh[x][y] = ( presetInputs->y_mesh[x][y] - presetOutputs->cy_mesh[x][y])/presetOutputs->sy_mesh[x][y] + presetOutputs->cy_mesh[x][y]; + presetOutputs->y_mesh[x][y] = ( presetOutputs->y_mesh[x][y] - presetOutputs->cy_mesh[x][y])/presetOutputs->sy_mesh[x][y] + presetOutputs->cy_mesh[x][y]; } } for (x=0;xgx;x++){ for(y=0;ygy;y++){ - float u2 = presetInputs->x_mesh[x][y] - presetOutputs->cx_mesh[x][y]; - float v2 = presetInputs->y_mesh[x][y] - presetOutputs->cy_mesh[x][y]; + float u2 = presetOutputs->x_mesh[x][y] - presetOutputs->cx_mesh[x][y]; + float v2 = presetOutputs->y_mesh[x][y] - presetOutputs->cy_mesh[x][y]; float cos_rot = cosf(presetOutputs->rot_mesh[x][y]); float sin_rot = sinf(presetOutputs->rot_mesh[x][y]); - presetInputs->x_mesh[x][y] = u2*cos_rot - v2*sin_rot + presetOutputs->cx_mesh[x][y]; - presetInputs->y_mesh[x][y] = u2*sin_rot + v2*cos_rot + presetOutputs->cy_mesh[x][y]; + presetOutputs->x_mesh[x][y] = u2*cos_rot - v2*sin_rot + presetOutputs->cx_mesh[x][y]; + presetOutputs->y_mesh[x][y] = u2*sin_rot + v2*cos_rot + presetOutputs->cy_mesh[x][y]; } } - if(presetOutputs->dx_is_mesh) - { + for (x=0;xgx;x++){ for(y=0;ygy;y++){ - presetInputs->x_mesh[x][y] -= presetOutputs->dx_mesh[x][y]; + presetOutputs->x_mesh[x][y] -= presetOutputs->dx_mesh[x][y]; } } - } + + - if(presetOutputs->dy_is_mesh) - { for (x=0;xgx;x++){ for(y=0;ygy;y++){ - presetInputs->y_mesh[x][y] -= presetOutputs->dy_mesh[x][y]; + presetOutputs->y_mesh[x][y] -= presetOutputs->dy_mesh[x][y]; } } - } + } @@ -1483,8 +1498,8 @@ void Renderer::draw_preset() { title_font->FaceSize((unsigned)(12*(this->vh/512.0))); if(this->noSwitch) title_font->Render("[LOCKED] " ); title_font->FaceSize((unsigned)(20*(this->vh/512.0))); - // std::cout << this->presetName; - title_font->Render(this->presetName.c_str() ); + + // title_font->Render(this->presetName.c_str() ); @@ -1909,7 +1924,7 @@ void Renderer::render_texture_to_studio(PresetOutputs *presetOutputs, PresetInpu for (x=0;xgx;x++){ glBegin(GL_LINE_STRIP); for(y=0;ygy;y++){ - glVertex4f((presetInputs->x_mesh[x][y]-.5), (presetInputs->y_mesh[x][y]-.5),-1,1); + glVertex4f((presetOutputs->x_mesh[x][y]-.5), (presetOutputs->y_mesh[x][y]-.5),-1,1); //glVertex4f((origx[x+1][y]-.5) * vw, (origy[x+1][y]-.5) *vh ,-1,1); } glEnd(); @@ -1918,7 +1933,7 @@ void Renderer::render_texture_to_studio(PresetOutputs *presetOutputs, PresetInpu for (y=0;ygy;y++){ glBegin(GL_LINE_STRIP); for(x=0;xgx;x++){ - glVertex4f((presetInputs->x_mesh[x][y]-.5), (presetInputs->y_mesh[x][y]-.5),-1,1); + glVertex4f((presetOutputs->x_mesh[x][y]-.5), (presetOutputs->y_mesh[x][y]-.5),-1,1); //glVertex4f((origx[x+1][y]-.5) * vw, (origy[x+1][y]-.5) *vh ,-1,1); } glEnd(); diff --git a/src/projectM-engine/Renderer.hpp b/src/projectM-engine/Renderer.hpp index b5d2d1036..3945a66ac 100644 --- a/src/projectM-engine/Renderer.hpp +++ b/src/projectM-engine/Renderer.hpp @@ -65,12 +65,13 @@ char *title; ~Renderer(); void RenderFrame(PresetOutputs *presetOutputs, PresetInputs *presetInputs); void reset(int w, int h); + void PerPixelMath(PresetOutputs *presetOutputs, PresetInputs *presetInputs); private: void PerFrame(PresetOutputs *presetOutputs); void Interpolation(PresetOutputs *presetOutputs, PresetInputs *presetInputs); - void PerPixelMath(PresetOutputs *presetOutputs, PresetInputs *presetInputs); + void rescale_per_pixel_matrices(); void maximize_colors(PresetOutputs *presetOutputs); void render_texture_to_screen(PresetOutputs *presetOutputs); diff --git a/src/projectM-engine/console_interface.cpp b/src/projectM-engine/console_interface.cpp index b9705ba15..ef11b206f 100755 --- a/src/projectM-engine/console_interface.cpp +++ b/src/projectM-engine/console_interface.cpp @@ -169,6 +169,9 @@ void projectM::default_key_handler( projectMEvent event, projectMKeycode keycode m_activePreset = std::auto_ptr(0); m_activePreset = m_presetPos->allocate(this->presetInputs, this->presetOutputs); + + presetInputs.frame = 0; + smoothFrame = 0; break; case PROJECTM_K_r: diff --git a/src/projectM-engine/projectM.cpp b/src/projectM-engine/projectM.cpp index 193dd867f..e0a97bc21 100755 --- a/src/projectM-engine/projectM.cpp +++ b/src/projectM-engine/projectM.cpp @@ -42,11 +42,13 @@ #include "Parser.hpp" #include "Preset.hpp" #include "PerPixelEqn.hpp" +#include "PresetMerge.hpp" //#include "menu.h" #include "PCM.hpp" //Sound data handler (buffering, FFT, etc.) #include "CustomWave.hpp" #include "CustomShape.hpp" #include + #include "Renderer.hpp" #include "PresetChooser.hpp" @@ -71,6 +73,9 @@ projectM *projectM::currentEngine = NULL; RenderTarget * projectM::renderTarget = NULL; Renderer * projectM::renderer = NULL; +float smoothTime = 5; +//int smoothFrame = 0; +int oldFrame = 0; DLLEXPORT projectM::projectM() :beatDetect ( 0 ) { @@ -81,44 +86,43 @@ DLLEXPORT projectM::projectM() :beatDetect ( 0 ) DLLEXPORT void projectM::renderFrame() { -#ifdef DEBUG - char fname[1024]; - FILE *f = NULL; - int index = 0; - int x, y; +#ifdef DEBUG + char fname[1024]; + FILE *f = NULL; + int index = 0; + int x, y; #endif - -// printf("Start of loop at %d\n",timestart); - mspf= ( int ) ( 1000.0/ ( float ) presetInputs.fps ); //milliseconds per frame - - + + // printf("Start of loop at %d\n",timestart); + mspf= ( int ) ( 1000.0/ ( float ) presetInputs.fps ); //milliseconds per frame + + #ifndef WIN32 - presetInputs.time = getTicks ( &startTime ) * 0.001; + presetInputs.time = getTicks ( &startTime ) * 0.001; #else - presetInputs.time = getTicks ( startTime ) * 0.001; + presetInputs.time = getTicks ( startTime ) * 0.001; #endif /** !WIN32 */ - - presetInputs.frame++; //number of frames for current preset - presetInputs.progress= presetInputs.frame/ ( float ) avgtime; - DWRITE ( "frame: %d\ttime: %f\tprogress: %f\tavgtime: %d\tang: %f\trot: %f\n", - this->presetInputs.frame, presetInputs.time, this->presetInputs.progress, this->avgtime, this->presetInputs.ang_per_pixel, - this->presetOutputs.rot ); + + + //DWRITE ( "frame: %d\ttime: %f\tprogress: %f\tavgtime: %d\tang: %f\trot: %f\n", + // this->presetInputs.frame, presetInputs.time, this->presetInputs.progress, this->avgtime, this->presetInputs.ang_per_pixel, + //this->presetOutputs.rot ); // printf("start:%d at:%d min:%d stop:%d on:%d %d\n",startframe, frame frame-startframe,avgtime, noSwitch,progress); - presetInputs.ResetMesh(); - + presetInputs.ResetMesh(); + // printf("%f %d\n",Time,frame); - beatDetect->detectFromSamples(); - DWRITE ( "=== vol: %f\tbass: %f\tmid: %f\ttreb: %f ===\n", - beatDetect->vol,beatDetect->bass,beatDetect->mid,beatDetect->treb ); - DWRITE ( "=== bass_att: %f ===\n", + beatDetect->detectFromSamples(); + DWRITE ( "=== vol: %f\tbass: %f\tmid: %f\ttreb: %f ===\n", + beatDetect->vol,beatDetect->bass,beatDetect->mid,beatDetect->treb ); + DWRITE ( "=== bass_att: %f ===\n", beatDetect->bass_att ); - + presetInputs.bass = beatDetect->bass; presetInputs.mid = beatDetect->mid; presetInputs.treb = beatDetect->treb; @@ -129,32 +133,76 @@ DLLEXPORT void projectM::renderFrame() assert(m_activePreset.get()); m_activePreset->evaluateFrame(); + if ( renderer->noSwitch==0 ) { if ( presetInputs.progress>1.0 ) { presetInputs.progress=0.0; presetInputs.frame = 0; - m_activePreset = m_presetChooser->weightedRandom - (presetInputs, presetOutputs); - nohard=presetInputs.fps*5; - printf("SOFT CUT"); + + m_activePreset2 = m_presetChooser->weightedRandom + (presetInputs, &m_activePreset->m_presetOutputs == &presetOutputs ? presetOutputs2 : presetOutputs); + nohard=(int)(presetInputs.fps*3.5); + smoothFrame = (int)(presetInputs.fps * smoothTime); + + printf("SOFT CUT - Smooth started\n"); } - else if ( ( beatDetect->bass-beatDetect->bass_old>beatDetect->beat_sensitivity ) && nohard<0 ) + else if ( ( beatDetect->bass-beatDetect->bass_old>beatDetect->beat_sensitivity ) && nohard<0 && false )//@REMOVE { // printf("%f %d %d\n", beatDetect->bass-beatDetect->bass_old,this->frame,this->avgtime); printf("HARD CUT"); m_activePreset = m_presetChooser->weightedRandom (presetInputs, presetOutputs); nohard=presetInputs.fps*5; + smoothFrame=0; } else nohard--; } - + + + if (smoothFrame > 1) + { + int frame = presetInputs.frame++; + presetInputs.frame = oldFrame; + presetInputs.progress= 1.0; + m_activePreset->evaluateFrame(); + renderer->PerPixelMath(&m_activePreset->m_presetOutputs, &presetInputs); + + presetInputs.frame = frame; + presetInputs.progress= frame /(float) avgtime; + m_activePreset2->evaluateFrame(); + renderer->PerPixelMath(&m_activePreset2->m_presetOutputs, &presetInputs); + + double ratio = smoothFrame / (presetInputs.fps * smoothTime); + + PresetMerger::MergePresets(m_activePreset->m_presetOutputs,m_activePreset2->m_presetOutputs,ratio,presetInputs.gx, presetInputs.gy); + + //printf("Smooth:%d\n",smoothFrame); + + smoothFrame--; + + } + else + { + if (smoothFrame == 1) + { + m_activePreset = m_activePreset2; + smoothFrame=0; + printf("Smooth Finished\n"); + } + + presetInputs.frame++; //number of frames for current preset + presetInputs.progress= presetInputs.frame/ ( float ) avgtime; + m_activePreset->evaluateFrame(); + renderer->PerPixelMath(&m_activePreset->m_presetOutputs, &presetInputs); + } + + // std::cout<< m_activePreset->absoluteFilePath()<presetName = m_activePreset->absoluteFilePath(); - m_activePreset->evaluateFrame(); - renderer->RenderFrame ( &presetOutputs, &presetInputs ); + + renderer->RenderFrame ( &m_activePreset->m_presetOutputs, &presetInputs ); count++; #ifndef WIN32 @@ -240,6 +288,7 @@ DLLEXPORT void projectM::projectM_init ( int gx, int gy, int fps, int texsize, i projectM_initengine(); presetInputs.Initialize ( gx, gy ); presetOutputs.Initialize ( gx, gy ); + presetOutputs2.Initialize ( gx, gy ); DWRITE ( "projectM plugin: Initializing\n" ); @@ -389,7 +438,7 @@ DLLEXPORT void projectM::projectM_init ( int gx, int gy, int fps, int texsize, i DWRITE ( "post PCM init\n" ); #endif - this->avgtime=this->presetInputs.fps*20; + this->avgtime=this->presetInputs.fps*10; this->hasInit = 1; diff --git a/src/projectM-engine/projectM.hpp b/src/projectM-engine/projectM.hpp index 5f42c3253..1f6d090a2 100755 --- a/src/projectM-engine/projectM.hpp +++ b/src/projectM-engine/projectM.hpp @@ -134,6 +134,8 @@ public: int pcmframes; int freqframes; + + int smoothFrame; GLubyte *fbuffer; @@ -230,6 +232,7 @@ public: // Currently loaded preset- will be fancier when smooth preset switching std::auto_ptr m_activePreset; + std::auto_ptr m_activePreset2; /** All readonly variables * which are passed as inputs @@ -239,5 +242,6 @@ public: /** The presets modify these values. For now this is declared on stack * but might be better on heap for sake of smooth preset switching */ PresetOutputs presetOutputs; + PresetOutputs presetOutputs2; }; #endif