<commit_before>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
#include "wipemalloc.h"
#include "BuiltinFuncs.hpp"
#include "fatal.h"
#include "Common.hpp"
#include "compare.h"
#ifdef WIN32
#include "win32-dirent.h"
#endif

#include "timer.h"
#include <iostream>
#ifdef LINUX
#include "time.h"
#endif

//#include <xmms/plugin.h>
#include <iostream>
#include "projectM.hpp"
#include "BeatDetect.hpp"
#include "Eval.hpp"
#include "Param.hpp"
#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 <map>

#include "Renderer.hpp"
#include "PresetChooser.hpp"

#ifdef LINUX
const std::string projectM::PROJECTM_PRESET_PATH ( "/usr/share/projectM/presets/" );
#endif

#ifdef MACOS
const std::string projectM::PROJECTM_PRESET_PATH ( "/usr/share/projectM/presets/" );
#endif


#ifdef WIN32
const std::string projectM::PROJECTM_PRESET_PATH ( "C:\\Program Files\\ProjectM\\presets" );
#endif

/** Stash current engine */
projectM *projectM::currentEngine = NULL;

/** Static variable initialization involving the render. */
/// @bug These probably shouldn't be static!
RenderTarget * projectM::renderTarget = NULL;
Renderer * projectM::renderer = NULL;

float smoothTime = 5;
//int smoothFrame = 0;
int oldFrame = 0;

DLLEXPORT projectM::projectM() :smoothFrame(0), beatDetect ( 0 )
{

}


DLLEXPORT void projectM::renderFrame()
{

#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
  

#ifndef WIN32
  presetInputs.time = getTicks ( &startTime ) * 0.001;
#else
  presetInputs.time = getTicks ( startTime ) * 0.001;
#endif /** !WIN32 */
  
  
  //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();
 


//     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->bass_att );
  
        presetInputs.bass = beatDetect->bass; 
	presetInputs.mid = beatDetect->mid; 
	presetInputs.treb = beatDetect->treb; 
	presetInputs.bass_att = beatDetect->bass_att; 
	presetInputs.mid_att = beatDetect->mid_att; 
	presetInputs.treb_att = beatDetect->treb_att; 

	assert(m_activePreset.get());

	m_activePreset->evaluateFrame();

	if ( renderer->noSwitch==0 )
	{
	  if ( presetInputs.progress>1.0 )
	    {
	      presetInputs.progress=0.0;
	      presetInputs.frame = 0;

	      m_activePreset2 = m_presetChooser->weightedRandom<PresetChooser::UniformRandomFunctor>
		(presetInputs, &m_activePreset->presetOutputs() == &presetOutputs ? presetOutputs2 : presetOutputs);
	      assert(m_activePreset2.get());
	       renderer->setPresetName(m_activePreset2->absoluteFilePath());
		
             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 && false )//@REMOVE
	    {
	      //            printf("%f %d %d\n", beatDetect->bass-beatDetect->bass_old,this->frame,this->avgtime);
	      printf("HARD CUT");
	      m_activePreset = m_presetChooser->weightedRandom<PresetChooser::UniformRandomFunctor>
		(presetInputs, presetOutputs);
	      assert(m_activePreset.get());
	      nohard=presetInputs.fps*5;
	      smoothFrame=0;
	    }
	  else nohard--;
	}


      
        if (smoothFrame > 1)
	  {
	    int frame = presetInputs.frame++;
	    presetInputs.frame = oldFrame;
	    presetInputs.progress= 1.0;
	    assert(m_activePreset.get());
	    m_activePreset->evaluateFrame();
	    renderer->PerPixelMath(&m_activePreset->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset->presetOutputs(), &presetInputs, true);

	    presetInputs.frame = frame;
	    presetInputs.progress= frame /(float) avgtime;
	    assert(m_activePreset2.get());
	    m_activePreset2->evaluateFrame();	    
	    renderer->PerPixelMath(&m_activePreset2->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset2->presetOutputs(), &presetInputs, true);
 
	    double ratio = smoothFrame / (presetInputs.fps * smoothTime); 

	    PresetMerger::MergePresets(m_activePreset->presetOutputs(),m_activePreset2->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->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset->presetOutputs(), &presetInputs, false);

	  }
	
	//	std::cout<< m_activePreset->absoluteFilePath()<<std::endl;
	//	renderer->presetName = m_activePreset->absoluteFilePath();

	renderer->RenderFrame ( &m_activePreset->presetOutputs(), &presetInputs );

	count++;
#ifndef WIN32
	/** Frame-rate limiter */
	/** Compute once per preset */
	if ( this->count%100==0 )
	{
		this->renderer->realfps=100.0/ ( ( getTicks ( &this->startTime )-this->fpsstart ) /1000 );
		this->fpsstart=getTicks ( &this->startTime );
	}

	int timediff = getTicks ( &this->startTime )-this->timestart;

	if ( timediff < this->mspf )
	{
		// printf("%s:",this->mspf-timediff);
		int sleepTime = ( unsigned int ) ( this->mspf-timediff ) * 1000;
		DWRITE ( "usleep: %d\n", sleepTime );
		if ( sleepTime > 0 && sleepTime < 100000 )
		{
			if ( usleep ( sleepTime ) != 0 ) {}}
	}
	this->timestart=getTicks ( &this->startTime );
#endif /** !WIN32 */

	DWRITE ( "exiting renderFrame()\n" );
}

DLLEXPORT void projectM::projectM_reset()
{

//    DWRITE( "projectM_reset(): in\n" );

	/// @bug uncertain if preset should be played with here - carm
//    m_activePreset = 0;

//    if (m_activePreset) {
//	delete(m_activePreset);
	//  	m_activePreset = 0;
	// }

	this->presetURL = NULL;
	this->fontURL = NULL;

	/** Default variable settings */
	this->hasInit = 0;

	this->pcmframes = 1;
	this->freqframes = 0;



	this->fvw = 800;
	this->fvh = 600;
	this->wvw = 512;
	this->wvh = 512;
	this->fullscreen = 0;

	/** Frames per preset */
	this->avgtime = 500;



	/** More other stuff */
	this->mspf = 0;
	this->timed = 0;
	this->timestart = 0;
	this->nohard = 0;
	this->count = 0;

	this->fpsstart = 0;

	projectM_resetengine();
}

DLLEXPORT void projectM::projectM_init ( int gx, int gy, int fps, int texsize, int width, int height )
{



	/** Initialise engine variables */

	projectM_initengine();
	presetInputs.Initialize ( gx, gy );
	presetOutputs.Initialize ( gx, gy );
	presetOutputs2.Initialize ( gx, gy );

	DWRITE ( "projectM plugin: Initializing\n" );

	/** Initialise start time */
#ifndef WIN32
	gettimeofday ( &this->startTime, NULL );
#else
	startTime = GetTickCount();
#endif /** !WIN32 */

	/** Nullify frame stash */
      

	/** Initialise per-pixel matrix calculations */


	presetInputs.fps = fps;

	/** We need to initialise this before the builtin param db otherwise bass/mid etc won't bind correctly */
	beatDetect = new BeatDetect();

	/* Preset loading function */
	initPresetTools();

	/* Load default preset directory */
#ifdef MACOS2
	/** Probe the bundle for info */
	CFBundleRef bundle = CFBundleGetMainBundle();
	char msg[1024];
	sprintf ( msg, "bundle: %X\n", bundle );
	DWRITE ( msg );
	if ( bundle != NULL )
	{
		CFPlugInRef pluginRef = CFBundleGetPlugIn ( bundle );
		if ( pluginRef != NULL )
		{
			DWRITE ( "located plugin ref\n" );
		}
		else
		{
			DWRITE ( "failed to find plugin ref\n" );
		}

		CFURLRef bundleURL = CFBundleCopyBundleURL ( bundle );
		if ( bundleURL == NULL )
		{
			DWRITE ( "bundleURL failed\n" );
		}
		else
		{
			DWRITE ( "bundleURL OK\n" );
		}
		char *bundleName =
		    ( char * ) CFStringGetCStringPtr ( CFURLGetString ( bundleURL ), kCFStringEncodingMacRoman );
		DWRITE ( "bundleURL: %s\n", bundleName );

		presetURL = CFBundleCopyResourceURL ( bundle, purl, NULL, NULL );
		if ( presetURL != NULL )
		{
			this->presetURL = ( char * ) CFStringGetCStringPtr ( CFURLCopyPath ( presetURL ), kCFStringEncodingMacRoman );
			sprintf ( msg, "Preset: %s\n", presetURL );
			DWRITE ( msg );
			printf ( msg );

			/** Stash the short preset name */

		}
		else
		{
			DWRITE ( "Failed to probe 'presets' bundle ref\n" );
			this->presetURL = NULL;
		}

		fontURL = CFBundleCopyResourceURL ( bundle, furl, NULL, NULL );
		if ( fontURL != NULL )
		{
			fontURL = ( char * ) CFStringGetCStringPtr ( CFURLCopyPath ( fontURL ), kCFStringEncodingMacRoman );
			sprintf ( msg, "Font: %s\n", fontURL );
			DWRITE ( msg );
			printf ( msg );
		}
		else
		{
			DWRITE ( "Failed to probe 'fonts' bundle ref\n" );
			fontURL = NULL;
		}
	}

	/** Sanity check */
	if ( bundle == NULL || presetURL == NULL || fontURL == NULL )
	{
		sprintf ( msg, "defaulting presets\n" );
		DWRITE ( msg );
		this->fontURL = ( char * ) wipemalloc ( sizeof ( char ) * 512 );
//        strcpy( this->fontURL, "../../fonts/" );
		strcpy ( fontURL, "/Users/descarte/tmp/projectM/fonts" );
		this->fontURL[34] = '\0';
//        loadPresetDir( "../../presets/" );
//        loadPresetDir( "/Users/descarte/tmp/projectM-1.00/presets_projectM" );
	}
	else
	{
		printf ( "PresetDir: %s\n", this->presetURL );
		loadPresetDir ( presetURL );
	}
#else
	if ( presetURL == NULL || fontURL == NULL )
	{
		char msg[1024];
		sprintf ( msg, "defaulting presets\n" );
		DWRITE ( msg );
		fontURL = ( char * ) wipemalloc ( sizeof ( char ) * 512 );
#ifdef WIN32
		strcpy ( this->fontURL, "c:\\tmp\\projectM\\fonts" );
		fontURL[24] = '\0';
#else
	strcpy ( this->fontURL, "/Users/descarte/tmp/projectM/fonts" );
	fontURL[34] = '\0';
#endif
		DWRITE ( "loading font URL directly: %s\n", this->fontURL );
#ifdef WIN32
		//      loadPresetDir( "c:\\tmp\\projectM\\presets_projectM" );
#else
	//    loadPresetDir( "/Users/descarte/tmp/projectM-1.00/presets_projectM" );
#endif
	}
	else
	{
		printf ( "PresetDir: %s\n", this->presetURL );
		//loadPresetDir( presetURL );
	}

#endif


	mspf= ( int ) ( 1000.0/ ( float ) presetInputs.fps );


//    initMenu();
//DWRITE( "post initMenu()\n" );

	printf ( "mesh: %d %d\n", gx,gy );

#ifdef PANTS
	printf ( "maxsamples: %d\n", this->maxsamples );
	initPCM ( this->maxsamples );
	DWRITE ( "post PCM init\n" );
#endif

	this->avgtime=this->presetInputs.fps*10;

	this->hasInit = 1;

	this->renderTarget = new RenderTarget ( texsize, width, height );
	this->presetInputs.gx = gx;
	this->presetInputs.gy = gy;

	this->renderer = new Renderer ( width, height, gx, gy, renderTarget, beatDetect, fontURL );
	renderer->setPresetName(m_activePreset->absoluteFilePath());

	printf ( "exiting projectM_init()\n" );
}




//calculate matrices for per_pixel




DLLEXPORT void projectM::projectM_initengine()<commit_msg>forgot--This line, and those below, will be ignored--<commit_after>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
#include "wipemalloc.h"
#include "BuiltinFuncs.hpp"
#include "fatal.h"
#include "Common.hpp"
#include "compare.h"
#ifdef WIN32
#include "win32-dirent.h"
#endif

#include "timer.h"
#include <iostream>
#ifdef LINUX
#include "time.h"
#endif

//#include <xmms/plugin.h>
#include <iostream>
#include "projectM.hpp"
#include "BeatDetect.hpp"
#include "Eval.hpp"
#include "Param.hpp"
#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 <map>

#include "Renderer.hpp"
#include "PresetChooser.hpp"

#ifdef LINUX
const std::string projectM::PROJECTM_PRESET_PATH ( "/usr/share/projectM/presets/" );
#endif

#ifdef MACOS
const std::string projectM::PROJECTM_PRESET_PATH ( "/usr/share/projectM/presets/" );
#endif


#ifdef WIN32
const std::string projectM::PROJECTM_PRESET_PATH ( "C:\\Program Files\\ProjectM\\presets" );
#endif

/** Stash current engine */
projectM *projectM::currentEngine = NULL;

/** Static variable initialization involving the render. */
/// @bug These probably shouldn't be static!
RenderTarget * projectM::renderTarget = NULL;
Renderer * projectM::renderer = NULL;

double presetDuration = 15;
double smoothDuration = 5;
//int smoothFrame = 0;
int oldFrame = 0;

DLLEXPORT projectM::projectM() :smoothFrame(0), beatDetect ( 0 )
{

}


DLLEXPORT void projectM::renderFrame()
{

#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
  

#ifndef WIN32
  presetInputs.time = getTicks ( &startTime ) * 0.001;
#else
  presetInputs.time = getTicks ( startTime ) * 0.001;
#endif /** !WIN32 */
  
  
  //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();
 


//     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->bass_att );
  
        presetInputs.bass = beatDetect->bass; 
	presetInputs.mid = beatDetect->mid; 
	presetInputs.treb = beatDetect->treb; 
	presetInputs.bass_att = beatDetect->bass_att; 
	presetInputs.mid_att = beatDetect->mid_att; 
	presetInputs.treb_att = beatDetect->treb_att; 

	assert(m_activePreset.get());

	m_activePreset->evaluateFrame();

	if ( renderer->noSwitch==0 )
	{
	  if ( presetInputs.progress>1.0 )
	    {
	      presetInputs.progress=0.0;
	      presetInputs.frame = 0;

	      m_activePreset2 = m_presetChooser->weightedRandom<PresetChooser::UniformRandomFunctor>
		(presetInputs, &m_activePreset->presetOutputs() == &presetOutputs ? presetOutputs2 : presetOutputs);
	      assert(m_activePreset2.get());
		renderer->setPresetName(m_activePreset2->absoluteFilePath());

             nohard=(int)(presetInputs.fps*3.5);
             smoothFrame = (int)(presetInputs.fps * smoothDuration);
	    
              printf("SOFT CUT - Smooth started\n");
	    }	  	  
	  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<PresetChooser::UniformRandomFunctor>
		(presetInputs, presetOutputs);
	      assert(m_activePreset.get());
	      nohard=presetInputs.fps*5;
	      smoothFrame=0;
	    }
	  else nohard--;
	}


      
        if (smoothFrame > 1)
	  {
	    int frame = presetInputs.frame++;
	    presetInputs.frame = oldFrame;
	    presetInputs.progress= 1.0;
	    assert(m_activePreset.get());
	    m_activePreset->evaluateFrame();
	    renderer->PerPixelMath(&m_activePreset->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset->presetOutputs(), &presetInputs, true);

	    presetInputs.frame = frame;
	    presetInputs.progress= frame /(float) avgtime;
	    assert(m_activePreset2.get());
	    m_activePreset2->evaluateFrame();
	    renderer->PerPixelMath(&m_activePreset2->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset2->presetOutputs(), &presetInputs, true);
 
            //double pos = -((smoothFrame / (presetInputs.fps * smoothDuration))-1);
	    //double ratio = 1/(1 + exp((pos-0.5)*4*M_PI));
	    double ratio = smoothFrame / (presetInputs.fps * smoothDuration);
	    // printf("f(%f)=%f\n",pos, ratio);
	    PresetMerger::MergePresets(m_activePreset->presetOutputs(),m_activePreset2->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->presetOutputs(), &presetInputs);
	    renderer->WaveformMath(&m_activePreset->presetOutputs(), &presetInputs, false);

	  }
	
	//	std::cout<< m_activePreset->absoluteFilePath()<<std::endl;
	//	renderer->presetName = m_activePreset->absoluteFilePath();

	renderer->RenderFrame ( &m_activePreset->presetOutputs(), &presetInputs );

	count++;
#ifndef WIN32
	/** Frame-rate limiter */
	/** Compute once per preset */
	if ( this->count%100==0 )
	{
		this->renderer->realfps=100.0/ ( ( getTicks ( &this->startTime )-this->fpsstart ) /1000 );
		this->fpsstart=getTicks ( &this->startTime );
	}

	int timediff = getTicks ( &this->startTime )-this->timestart;

	if ( timediff < this->mspf )
	{
		// printf("%s:",this->mspf-timediff);
		int sleepTime = ( unsigned int ) ( this->mspf-timediff ) * 1000;
		DWRITE ( "usleep: %d\n", sleepTime );
		if ( sleepTime > 0 && sleepTime < 100000 )
		{
			if ( usleep ( sleepTime ) != 0 ) {}}
	}
	this->timestart=getTicks ( &this->startTime );
#endif /** !WIN32 */

	DWRITE ( "exiting renderFrame()\n" );
}

DLLEXPORT void projectM::projectM_reset()
{

//    DWRITE( "projectM_reset(): in\n" );

	/// @bug uncertain if preset should be played with here - carm
//    m_activePreset = 0;

//    if (m_activePreset) {
//	delete(m_activePreset);
	//  	m_activePreset = 0;
	// }

	this->presetURL = NULL;
	this->fontURL = NULL;

	/** Default variable settings */
	this->hasInit = 0;

	this->pcmframes = 1;
	this->freqframes = 0;



	this->fvw = 800;
	this->fvh = 600;
	this->wvw = 512;
	this->wvh = 512;
	this->fullscreen = 0;

	/** Frames per preset */
	this->avgtime = 500;



	/** More other stuff */
	this->mspf = 0;
	this->timed = 0;
	this->timestart = 0;
	this->nohard = 0;
	this->count = 0;

	this->fpsstart = 0;

	projectM_resetengine();
}

DLLEXPORT void projectM::projectM_init ( int gx, int gy, int fps, int texsize, int width, int height )
{



	/** Initialise engine variables */

	projectM_initengine();
	presetInputs.Initialize ( gx, gy );
	presetOutputs.Initialize ( gx, gy );
	presetOutputs2.Initialize ( gx, gy );

	DWRITE ( "projectM plugin: Initializing\n" );

	/** Initialise start time */
#ifndef WIN32
	gettimeofday ( &this->startTime, NULL );
#else
	startTime = GetTickCount();
#endif /** !WIN32 */

	/** Nullify frame stash */
      

	/** Initialise per-pixel matrix calculations */


	presetInputs.fps = fps;

	/** We need to initialise this before the builtin param db otherwise bass/mid etc won't bind correctly */
	beatDetect = new BeatDetect();

	/* Preset loading function */
	initPresetTools();

	/* Load default preset directory */
#ifdef MACOS2
	/** Probe the bundle for info */
	CFBundleRef bundle = CFBundleGetMainBundle();
	char msg[1024];
	sprintf ( msg, "bundle: %X\n", bundle );
	DWRITE ( msg );
	if ( bundle != NULL )
	{
		CFPlugInRef pluginRef = CFBundleGetPlugIn ( bundle );
		if ( pluginRef != NULL )
		{
			DWRITE ( "located plugin ref\n" );
		}
		else
		{
			DWRITE ( "failed to find plugin ref\n" );
		}

		CFURLRef bundleURL = CFBundleCopyBundleURL ( bundle );
		if ( bundleURL == NULL )
		{
			DWRITE ( "bundleURL failed\n" );
		}
		else
		{
			DWRITE ( "bundleURL OK\n" );
		}
		char *bundleName =
		    ( char * ) CFStringGetCStringPtr ( CFURLGetString ( bundleURL ), kCFStringEncodingMacRoman );
		DWRITE ( "bundleURL: %s\n", bundleName );

		presetURL = CFBundleCopyResourceURL ( bundle, purl, NULL, NULL );
		if ( presetURL != NULL )
		{
			this->presetURL = ( char * ) CFStringGetCStringPtr ( CFURLCopyPath ( presetURL ), kCFStringEncodingMacRoman );
			sprintf ( msg, "Preset: %s\n", presetURL );
			DWRITE ( msg );
			printf ( msg );

			/** Stash the short preset name */

		}
		else
		{
			DWRITE ( "Failed to probe 'presets' bundle ref\n" );
			this->presetURL = NULL;
		}

		fontURL = CFBundleCopyResourceURL ( bundle, furl, NULL, NULL );
		if ( fontURL != NULL )
		{
			fontURL = ( char * ) CFStringGetCStringPtr ( CFURLCopyPath ( fontURL ), kCFStringEncodingMacRoman );
			sprintf ( msg, "Font: %s\n", fontURL );
			DWRITE ( msg );
			printf ( msg );
		}
		else
		{
			DWRITE ( "Failed to probe 'fonts' bundle ref\n" );
			fontURL = NULL;
		}
	}

	/** Sanity check */
	if ( bundle == NULL || presetURL == NULL || fontURL == NULL )
	{
		sprintf ( msg, "defaulting presets\n" );
		DWRITE ( msg );
		this->fontURL = ( char * ) wipemalloc ( sizeof ( char ) * 512 );
//        strcpy( this->fontURL, "../../fonts/" );
		strcpy ( fontURL, "/Users/descarte/tmp/projectM/fonts" );
		this->fontURL[34] = '\0';
//        loadPresetDir( "../../presets/" );
//        loadPresetDir( "/Users/descarte/tmp/projectM-1.00/presets_projectM" );
	}
	else
	{
		printf ( "PresetDir: %s\n", this->presetURL );
		loadPresetDir ( presetURL );
	}
#else
	if ( presetURL == NULL || fontURL == NULL )
	{
		char msg[1024];
		sprintf ( msg, "defaulting presets\n" );
		DWRITE ( msg );
		fontURL = ( char * ) wipemalloc ( sizeof ( char ) * 512 );
#ifdef WIN32
		strcpy ( this->fontURL, "c:\\tmp\\projectM\\fonts" );
		fontURL[24] = '\0';
#else
	strcpy ( this->fontURL, "/Users/descarte/tmp/projectM/fonts" );
	fontURL[34] = '\0';
#endif
		DWRITE ( "loading font URL directly: %s\n", this->fontURL );
#ifdef WIN32
		//      loadPresetDir( "c:\\tmp\\projectM\\presets_projectM" );
#else
	//    loadPresetDir( "/Users/descarte/tmp/projectM-1.00/presets_projectM" );
#endif
	}
	else
	{
		printf ( "PresetDir: %s\n", this->presetURL );
		//loadPresetDir( presetURL );
	}

#endif


	mspf= ( int ) ( 1000.0/ ( float ) presetInputs.fps );


//    initMenu();
//DWRITE( "post initMenu()\n" );

	printf ( "mesh: %d %d\n", gx,gy );

#ifdef PANTS
	printf ( "maxsamples: %d\n", this->maxsamples );
	initPCM ( this->maxsamples );
	DWRITE ( "post PCM init\n" );
#endif

	this->avgtime=(int)(this->presetInputs.fps*presetDuration);

	this->hasInit = 1;

	this->renderTarget = new RenderTarget ( texsize, width, height );
	this->presetInputs.gx = gx;
	this->presetInputs.gy = gy;

	this->renderer = new Renderer ( width, height, gx, gy, renderTarget, beatDetect, fontURL );
	renderer->setPresetName(m_activePreset->absoluteFilePath());

	printf ( "exiting projectM_init()\n" );
}




//calculate matrices for per_pixel




DLLEXPORT void projectM::projectM_initengine()
{'fraction_non_alphanumeric': 0.1527238125446039, 'fraction_numerical': 0.014907620331456664, 'mean_word_length': 3.4864816791177518, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 235, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '647329', 'n_tokens_mistral': 9627, 'n_tokens_neox': 8887, 'n_words': 1952}