/*
        Once we have the subtitle built, we do the u& v planes
        and some smoothing to avoid over sharpening on the chroma plane

*/
uint8_t ADMVideoSubtitle::doChroma(void)
{
// now blur bitmap into mask..
        memset(_maskBuffer,0,SRT_MAX_LINE*_conf->_fontsize*_info.width);

        uint32_t off;
        uint8_t *src,*dst;

        off=0;

        src=_bitmapBuffer;
        dst=_maskBuffer;


        // We shrink it down for u & v by 2x2
        // mask buffer->bitmap buffer

        uint8_t tmp[_info.width*_info.height];

        decimate(src,tmp,_info.width,_info.height);
        lowPass(src,dst,_info.width,_info.height);
        lowPass(tmp,src,_info.width>>1,_info.height>>1);

        if (_conf->_useBackgroundColor) 
        {
                decimate(_bgMaskBuffer,_bgBitmapBuffer,_info.width,_info.height);
                //lowPass(tmp,_bgBitmapBuffer,_info.width>>1,_info.height>>1);
        }
  
}
Beispiel #2
0
void convert(uint8_t img[], int* nrows, int* ncols, int ldim)
{
	int h, w, chrh, chrw;

	//
	h = *nrows;
	w = *ncols;
		
	//
	CLAHE(img, img, h, w, ldim, 8, 8, 2);
	
	//
	chrh = 16;
	chrw = 8;
	
	decimate(img, img, h, w, ldim, chrh, chrw);
	
	h = h/chrh;
	w = w/chrw;
	
	//
	CLAHE(img, img, h, w, w, 4, 8, 3);
	
	// pixel intensity quantization
	quantize(img, img, h, w, w);
	
	//
	*nrows = h;
	*ncols = w;
}
Beispiel #3
0
PointViewSet DecimationFilter::run(PointViewPtr inView)
{
    PointViewSet viewSet;
    PointViewPtr outView = inView->makeNew();
    decimate(*inView.get(), *outView.get());
    viewSet.insert(outView);
    return viewSet;
}
//
//	Display up to 3 lines of text centered on screen
//  Each line is separated by a |
//______________________________________
void ADMVideoSubtitle::displayString(char *string)
{
	uint32_t base,last=0,line=0;
	double bbase;

//	printf("%s\n",string);


					// bbase is the final position in line
					// in the image


					base=0;

					memset(_bitmapBuffer,0,_info.height*_info.width);
					memset(_maskBuffer,0,_info.height*_info.width);
					// search for | char
					for(uint32_t i=0;i<strlen(string);i++)
					{
						if( *(string+i)=='|')
							{
									displayLine(string+last,base,i-last);
									last=i+1;
									base+=_conf->_fontsize;
									line++;
									if(line>3)
									{
											printf("\n Maximum 3 lines!\n");
										 	return;
									}
							}
					}
				//printf("\len :%d\n",strlen(string)-last);
				displayLine(string+last,base,strlen(string)-last);

				// now blur bitmap into mask..
				memset(_maskBuffer,0,SRT_MAX_LINE*_conf->_fontsize*_info.width);

				uint32_t off;
				uint8_t *src,*dst;

				off=0;

				src=_bitmapBuffer;
				dst=_maskBuffer;


		// We shrink it down for u & v by 2x2
		// mask buffer->bitmap buffer

uint8_t tmp[_info.width*_info.height];

				decimate(src,tmp,_info.width,_info.height);
				lowPass(src,dst,_info.width,_info.height);
				lowPass(tmp,src,_info.width>>1,_info.height>>1);


}
Beispiel #5
0
bool DecimationMesh::decimate(unsigned int targetFaces)
{
  // We can't collapse down to less than two faces
  if (targetFaces < 2) targetFaces = 2;

  // Keep collapsing one edge at a time until the target is reached
  // or the heap is empty (when we have no possible collapses left)
  while (mFaces.size() - mNumCollapsedFaces > targetFaces && !mHeap.isEmpty())
    decimate();

  // Return true if target is reached
  std::cout << "Collapsed mesh to " << mFaces.size() - mNumCollapsedFaces << " faces" << std::endl;
  return mFaces.size() - mNumCollapsedFaces == targetFaces;
}
Beispiel #6
0
TEST(RealVectorMethods, ComplexDecimateEvenOdd) {
    std::complex<double> inputData[] = {std::complex<double>(1, 2), std::complex<double>(0, 3), std::complex<double>(-1, 4), std::complex<double>(-2, 5), std::complex<double>(-3, 6), std::complex<double>(-4, 7), std::complex<double>(-5, 8), std::complex<double>(-6, 9), std::complex<double>(-7, 10)};
    double filterTaps[] = {1, 2, 3, 4, 5};
    std::complex<double> expectedData[] = {std::complex<double>(1, 2), std::complex<double>(0, 30), std::complex<double>(-35, 80), std::complex<double>(-72, 114), std::complex<double>(-35, 50)};
    unsigned numElements = sizeof(inputData)/sizeof(inputData[0]);
	NimbleDSP::ComplexVector<double> buf(inputData, numElements);
    numElements = sizeof(filterTaps)/sizeof(filterTaps[0]);
    NimbleDSP::RealVector<double> filter(filterTaps, numElements);
    NimbleDSP::ComplexVector<double> input = buf;
    int rate = 3;
    
    decimate(buf, rate, filter);
    EXPECT_EQ((input.size() + filter.size() - 1 + (rate - 1))/rate, buf.size());
    for (unsigned i=0; i<buf.size(); i++) {
        EXPECT_EQ(expectedData[i], buf[i]);
    }
}
Beispiel #7
0
TEST(RealVectorFilter, DecimateEvenOdd) {
    double inputData[] = {1, 0, -1, -2, -3, -4, -5, -6, -7};
    int filterTaps[] = {1, 2, 3, 4, 5};
    double expectedData[] = {1, 0, -35, -72, -35};
    unsigned numElements = sizeof(inputData)/sizeof(inputData[0]);
	NimbleDSP::RealVector<double> buf(inputData, numElements);
    numElements = sizeof(filterTaps)/sizeof(filterTaps[0]);
    NimbleDSP::RealVector<double> filter(filterTaps, numElements);
    NimbleDSP::RealVector<double> input = buf;
    int rate = 3;
    
    decimate(buf, rate, filter);
    EXPECT_EQ((input.size() + filter.size() - 1 + (rate - 1))/rate, buf.size());
    for (unsigned i=0; i<buf.size(); i++) {
        EXPECT_EQ(expectedData[i], buf[i]);
    }
}
IGL_INLINE bool igl::copyleft::progressive_hulls(
  const Eigen::MatrixXd & V,
  const Eigen::MatrixXi & F,
  const size_t max_m,
  Eigen::MatrixXd & U,
  Eigen::MatrixXi & G,
  Eigen::VectorXi & J)
{
  int m = F.rows();
  Eigen::VectorXi I;
  return decimate(
    V,
    F,
    progressive_hulls_cost_and_placement,
    max_faces_stopping_condition(m,max_m),
    U,
    G,
    J,
    I);
}
Beispiel #9
0
            u::bytes microphone::read_data()
            {
                REQUIRE(_d);
                if(!_d) return {};

                INVARIANT(_i);

                auto len = _i->bytesReady();
                if(len <= 0) return {};
                if(static_cast<size_t>(len) > MAX_SAMPLE_BYTES) len = MAX_SAMPLE_BYTES;

                u::bytes data;
                data.resize(len);

                auto l = _d->read(data.data(), len);
                if(l <= 0) return {};
                data.resize(l);

                //decimate and add to buffer
                decimate(data, _buffer, _channels, _skip);

                if(_buffer.size() < MIN_BUF_SIZE) return {};

                //once we have enough data, do noise reduction
                reduce_noise(_buffer, MIN_BUF_SIZE);

                //copy buffer to result
                u::bytes r(_buffer.begin(), _buffer.begin() + MIN_BUF_SIZE);

                //copy extra to front and resize. Probably a better idea to use a circular buf here.
                auto final_buf_size = _buffer.size() - MIN_BUF_SIZE;
                std::copy(_buffer.begin() + MIN_BUF_SIZE, _buffer.end(), _buffer.begin());
                _buffer.resize(final_buf_size);

                return r;
            }
Beispiel #10
0
int	wrapped_main(int argc, char* argv[])
{
	// Process command-line options.
	char*	infile = NULL;
	char*	outfile = NULL;
	int	factor = 16;

	for ( int arg = 1; arg < argc; arg++ ) {
		if ( argv[arg][0] == '-' ) {
			// command-line switch.
			
			switch ( argv[arg][1] ) {
			case 'h':
			case '?':
				print_usage();
				exit( 1 );
				break;

			case 'x':
				// Get decimation factor.
				if (arg + 1 >= argc) {
					printf("error: -x option requires a reduction factor\n");
					print_usage();
					exit(1);
				}
				arg++;
				factor = atoi(argv[arg]);
				if (factor <= 0 || factor > 256) {
					printf("error: bad reduction factor\n");
					print_usage();
					exit(1);
				}
				break;
				
			default:
				printf("error: unknown command-line switch -%c\n", argv[arg][1]);
				exit(1);
				break;
			}

		} else {
			// File argument.
			if (infile == NULL) {
				infile = argv[arg];
			} else if (outfile == NULL) {
				outfile = argv[arg];
			} else {
				// This looks like extra noise on the command line; complain and exit.
				printf( "argument '%s' looks like extra noise; exiting.\n", argv[arg]);
				print_usage();
				exit( 1 );
			}
		}
	}

	// Make sure we have input and output filenames.
	if (infile == NULL || outfile == NULL) {
		// No input or output -- can't run.
		printf( "error: you must specify input and output filenames.\n" );
		print_usage();
		exit( 1 );
	}
	
	SDL_RWops*	in = SDL_RWFromFile(infile, "rb");
	if (in == 0) {
		printf("error: can't open %s for input.\n", outfile);
		exit(1);
	}

	SDL_RWops*	out = SDL_RWFromFile(outfile, "wb");
	if (out == 0) {
		printf("error: can't open %s for output.\n", outfile);
		exit(1);
	}

	decimate(out, in, factor);

	SDL_RWclose(in);
	SDL_RWclose(out);

	return 0;
}
Beispiel #11
0
/* --------------------------------------------------------------------------------------------*/
double Synapse(double *ihcout, double tdres, double cf, int totalstim, int nrep, double spont, double noiseType, double implnt, double sampFreq, double *synouttmp)
{
    /* Initalize Variables */
    int z, b;
    int resamp = (int) ceil(1/(tdres*sampFreq));
    double incr = 0.0; int delaypoint = (int) floor(7500/(cf/1e3));

    double alpha1, beta1, I1, alpha2, beta2, I2, binwidth;
    int    k,j,indx,i;
    double synstrength,synslope,CI,CL,PG,CG,VL,PL,VI;
	double cf_factor,PImax,kslope,Ass,Asp,TauR,TauST,Ar_Ast,PTS,Aon,AR,AST,Prest,gamma1,gamma2,k1,k2;
	double VI0,VI1,alpha,beta,theta1,theta2,theta3,vsat,tmpst,tmp,PPI,CIlast,temp;

    double *sout1, *sout2, *synSampOut, *powerLawIn, *exponOut, *TmpSyn;
    double *m1, *m2, *m3, *m4, *m5;
	double *n1, *n2, *n3;

    double *randNums;

    double *sampIHC, *ihcDims;

    exponOut = (double*)calloc((long) ceil(totalstim*nrep),sizeof(double));
    powerLawIn = (double*)calloc((long) ceil(totalstim*nrep+3*delaypoint),sizeof(double));
    sout1 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    sout2 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    synSampOut  = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    TmpSyn  = (double*)calloc((long) ceil(totalstim*nrep+2*delaypoint),sizeof(double));

    m1 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    m2 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    m3  = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    m4 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    m5  = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));

    n1 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    n2 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));
    n3 = (double*)calloc((long) ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),sizeof(double));

    /*----------------------------------------------------------*/
    /*------- Parameters of the Power-law function -------------*/
    /*----------------------------------------------------------*/
    binwidth = 1/sampFreq;
    /*alpha1 = 5e-6*100e3; beta1 = 5e-4; I1 = 0;*/ /* older version, 2012 and before */
    alpha1 = 2.5e-6*100e3; beta1 = 5e-4; I1 = 0;
    alpha2 = 1e-2*100e3; beta2 = 1e-1; I2 = 0;
    /*----------------------------------------------------------*/
    /*------- Generating a random sequence ---------------------*/
    /*----------------------------------------------------------*/
     randNums = ffGn((int)ceil((totalstim*nrep+2*delaypoint)*tdres*sampFreq),
		     1/sampFreq,
		     0.9,
		     noiseType,
		     spont);

    /*----------------------------------------------------------*/
    /*----- Double Exponential Adaptation ----------------------*/
    /*----------------------------------------------------------*/
       if (spont==100) cf_factor = __min(800,pow(10,0.29*cf/1e3 + 0.7));
       if (spont==4)   cf_factor = __min(50,2.5e-4*cf*4+0.2);
       if (spont==0.1) cf_factor = __min(1.0,2.5e-4*cf*0.1+0.15);

	   PImax  = 0.6;                /* PI2 : Maximum of the PI(PI at steady state) */
       kslope = (1+50.0)/(5+50.0)*cf_factor*20.0*PImax;
       /* Ass    = 300*TWOPI/2*(1+cf/100e3); */  /* Older value: Steady State Firing Rate eq.10 */
       Ass    = 800*(1+cf/100e3);    /* Steady State Firing Rate eq.10 */

       if (implnt==1) Asp = spont*3.0;   /* Spontaneous Firing Rate if actual implementation */
       if (implnt==0) Asp = spont*2.75; /* Spontaneous Firing Rate if approximate implementation */
       TauR   = 2e-3;               /* Rapid Time Constant eq.10 */
       TauST  = 60e-3;              /* Short Time Constant eq.10 */
       Ar_Ast = 6;                  /* Ratio of Ar/Ast */
       PTS    = 3;                  /* Peak to Steady State Ratio, characteristic of PSTH */

       /* now get the other parameters */
       Aon    = PTS*Ass;                          /* Onset rate = Ass+Ar+Ast eq.10 */
       AR     = (Aon-Ass)*Ar_Ast/(1+Ar_Ast);      /* Rapid component magnitude: eq.10 */
       AST    = Aon-Ass-AR;                       /* Short time component: eq.10 */
       Prest  = PImax/Aon*Asp;                    /* eq.A15 */
       CG  = (Asp*(Aon-Asp))/(Aon*Prest*(1-Asp/Ass));    /* eq.A16 */
       gamma1 = CG/Asp;                           /* eq.A19 */
       gamma2 = CG/Ass;                           /* eq.A20 */
       k1     = -1/TauR;                          /* eq.8 & eq.10 */
       k2     = -1/TauST;                         /* eq.8 & eq.10 */
               /* eq.A21 & eq.A22 */
       VI0    = (1-PImax/Prest)/(gamma1*(AR*(k1-k2)/CG/PImax+k2/Prest/gamma1-k2/PImax/gamma2));
       VI1    = (1-PImax/Prest)/(gamma1*(AST*(k2-k1)/CG/PImax+k1/Prest/gamma1-k1/PImax/gamma2));
       VI  = (VI0+VI1)/2;
       alpha  = gamma2/k1/k2;       /* eq.A23,eq.A24 or eq.7 */
       beta   = -(k1+k2)*alpha;     /* eq.A23 or eq.7 */
       theta1 = alpha*PImax/VI;
       theta2 = VI/PImax;
       theta3 = gamma2-1/PImax;

       PL  = ((beta-theta2*theta3)/theta1-1)*PImax;  /* eq.4' */
       PG  = 1/(theta3-1/PL);                        /* eq.5' */
       VL  = theta1*PL*PG;                           /* eq.3' */
       CI  = Asp/Prest;                              /* CI at rest, from eq.A3,eq.A12 */
       CL  = CI*(Prest+PL)/PL;                       /* CL at rest, from eq.1 */

       if(kslope>=0)  vsat = kslope+Prest;
       tmpst  = log(2)*vsat/Prest;
       if(tmpst<400) synstrength = log(exp(tmpst)-1);
       else synstrength = tmpst;
       synslope = Prest/log(2)*synstrength;

       k = 0;
       for (indx=0; indx<totalstim*nrep; ++indx)
       {
            tmp = synstrength*(ihcout[indx]);
            if(tmp<400) tmp = log(1+exp(tmp));
            PPI = synslope/synstrength*tmp;

            CIlast = CI;
            CI = CI + (tdres/VI)*(-PPI*CI + PL*(CL-CI));
            CL = CL + (tdres/VL)*(-PL*(CL - CIlast) + PG*(CG - CL));
            if(CI<0)
            {
                temp = 1/PG+1/PL+1/PPI;
                CI = CG/(PPI*temp);
                CL = CI*(PPI+PL)/PL;
            };
            exponOut[k] = CI*PPI;
            k=k+1;
        }
        for (k=0; k<delaypoint; k++)
			powerLawIn[k] = exponOut[0];
        for (k=delaypoint; k<totalstim*nrep+delaypoint; k++)
			powerLawIn[k] = exponOut[k-delaypoint];
        for (k=totalstim*nrep+delaypoint; k<totalstim*nrep+3*delaypoint; k++)
			powerLawIn[k] = powerLawIn[k-1];
   /*----------------------------------------------------------*/
   /*------ Downsampling to sampFreq (Low) sampling rate ------*/
   /*----------------------------------------------------------*/
	sampIHC = decimate(k, powerLawIn, resamp);


    free(powerLawIn); free(exponOut);
   /*----------------------------------------------------------*/
   /*----- Running Power-law Adaptation -----------------------*/
   /*----------------------------------------------------------*/
    k = 0;
    for (indx=0; indx<floor((totalstim*nrep+2*delaypoint)*tdres*sampFreq); indx++)
    {
          sout1[k]  = __max( 0, sampIHC[indx] + randNums[indx]- alpha1*I1);
          /*sout1[k]  = __max( 0, sampIHC[indx] - alpha1*I1); */   /* No fGn condition */
          sout2[k]  = __max( 0, sampIHC[indx] - alpha2*I2);

         if (implnt==1)    /* ACTUAL Implementation */
         {
              I1 = 0; I2 = 0;
              for (j=0; j<k+1; ++j)
                  {
                      I1 += (sout1[j])*binwidth/((k-j)*binwidth + beta1);
                      I2 += (sout2[j])*binwidth/((k-j)*binwidth + beta2);
                   }
         } /* end of actual */

         if (implnt==0)    /* APPROXIMATE Implementation */
         {
                if (k==0)
                {
                    n1[k] = 1.0e-3*sout2[k];
                    n2[k] = n1[k]; n3[0]= n2[k];
                }
                else if (k==1)
                {
                    n1[k] = 1.992127932802320*n1[k-1]+ 1.0e-3*(sout2[k] - 0.994466986569624*sout2[k-1]);
                    n2[k] = 1.999195329360981*n2[k-1]+ n1[k] - 1.997855276593802*n1[k-1];
                    n3[k] = -0.798261718183851*n3[k-1]+ n2[k] + 0.798261718184977*n2[k-1];
                }
                else
                {
                    n1[k] = 1.992127932802320*n1[k-1] - 0.992140616993846*n1[k-2]+ 1.0e-3*(sout2[k] - 0.994466986569624*sout2[k-1] + 0.000000000002347*sout2[k-2]);
                    n2[k] = 1.999195329360981*n2[k-1] - 0.999195402928777*n2[k-2]+n1[k] - 1.997855276593802*n1[k-1] + 0.997855827934345*n1[k-2];
                    n3[k] =-0.798261718183851*n3[k-1] - 0.199131619873480*n3[k-2]+n2[k] + 0.798261718184977*n2[k-1] + 0.199131619874064*n2[k-2];
                }
                I2 = n3[k];

                if (k==0)
                {
                    m1[k] = 0.2*sout1[k];
                    m2[k] = m1[k];	m3[k] = m2[k];
                    m4[k] = m3[k];	m5[k] = m4[k];
                }
                else if (k==1)
                {
                    m1[k] = 0.491115852967412*m1[k-1] + 0.2*(sout1[k] - 0.173492003319319*sout1[k-1]);
                    m2[k] = 1.084520302502860*m2[k-1] + m1[k] - 0.803462163297112*m1[k-1];
                    m3[k] = 1.588427084535629*m3[k-1] + m2[k] - 1.416084732997016*m2[k-1];
                    m4[k] = 1.886287488516458*m4[k-1] + m3[k] - 1.830362725074550*m3[k-1];
                    m5[k] = 1.989549282714008*m5[k-1] + m4[k] - 1.983165053215032*m4[k-1];
                }
                else
                {
                    m1[k] = 0.491115852967412*m1[k-1] - 0.055050209956838*m1[k-2]+ 0.2*(sout1[k]- 0.173492003319319*sout1[k-1]+ 0.000000172983796*sout1[k-2]);
                    m2[k] = 1.084520302502860*m2[k-1] - 0.288760329320566*m2[k-2] + m1[k] - 0.803462163297112*m1[k-1] + 0.154962026341513*m1[k-2];
                    m3[k] = 1.588427084535629*m3[k-1] - 0.628138993662508*m3[k-2] + m2[k] - 1.416084732997016*m2[k-1] + 0.496615555008723*m2[k-2];
                    m4[k] = 1.886287488516458*m4[k-1] - 0.888972875389923*m4[k-2] + m3[k] - 1.830362725074550*m3[k-1] + 0.836399964176882*m3[k-2];
                    m5[k] = 1.989549282714008*m5[k-1] - 0.989558985673023*m5[k-2] + m4[k] - 1.983165053215032*m4[k-1] + 0.983193027347456*m4[k-2];
                }
                I1 = m5[k];
            } /* end of approximate implementation */

        synSampOut[k] = sout1[k] + sout2[k];
        k = k+1;
      }   /* end of all samples */
      free(sout1); free(sout2);
      free(m1); free(m2); free(m3); free(m4); free(m5); free(n1); free(n2); free(n3);
    /*----------------------------------------------------------*/
    /*----- Upsampling to original (High 100 kHz) sampling rate --------*/
    /*----------------------------------------------------------*/
    for(z=0; z<k-1; ++z)
    {
        incr = (synSampOut[z+1]-synSampOut[z])/resamp;
        for(b=0; b<resamp; ++b)
        {
            TmpSyn[z*resamp+b] = synSampOut[z]+ b*incr;
        }
    }
    for (i=0;i<totalstim*nrep;++i)
        synouttmp[i] = TmpSyn[i+delaypoint];

    free(synSampOut); free(TmpSyn);
    free(randNums);
    free(sampIHC);

    return((long) ceil(totalstim*nrep));
}
int main(int argc, char *argv[])
{
  if(argc != 6)
  {
      std::cout << "Usage: obj_to_vtk_and_stl InputObjFile OutputStlFile OutputVtkFile maxNPointsMeshShouldHaveAfterDecimation ScaleToConvertObjMeshToMM" << std::endl;
      return EXIT_SUCCESS;
  }
  std::string inputFileName = argv[1];
  std::string outputFileNameStl = argv[2];
  std::string outputFileNameVtk = argv[3];
  int maxNPoints = atoi(argv[4]);
  float scale = atof(argv[5]);

  std::cout << "Reading " << inputFileName << std::endl;
  vtkSmartPointer<vtkPolyData> input;
  loadModel(inputFileName, input);

  std::cout << "Input has normals: " << GetPointNormals(input) << std::endl;
  if(!GetPointNormals(input))
  {
    std::cout << "WARNING: Input mesh, does not have normals! Resulting vtk file will not have normals." << std::endl;
  }

  int maxIterations = 25;
  int curIteration = 0;
  std::cout << "Trying to decimate mesh to maximal  " << maxNPoints << "points within maximal " << maxIterations << " iterations." << std::endl;
  std::cout << ".. " << curIteration << ": NPoints " << input->GetNumberOfPoints() << std::endl;
  while(input->GetNumberOfPoints() > maxNPoints && ++curIteration < maxIterations)
  {
    {
    vtkSmartPointer<vtkPolyData> temp = decimate(input, 0.5);
    input = temp;
    }
    std::cout << ".. " << curIteration << ": NPoints " << input->GetNumberOfPoints() << std::endl;
  }

  std::cout << "Applying scaling by factor or " << scale << std::endl;
  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
  transform->Scale(scale,scale,scale);
  vtkSmartPointer<vtkTransformPolyDataFilter> scaleFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  scaleFilter->SetInput(input);
  scaleFilter->SetTransform(transform);
  scaleFilter->Update();
  vtkSmartPointer<vtkPolyData> transformed = scaleFilter->GetOutput();


  std::cout << "Saving stl..." << std::endl;
  vtkSmartPointer<vtkSTLWriter> writer = vtkSmartPointer<vtkSTLWriter>::New();
  writer->SetFileName(outputFileNameStl.c_str());
  writer->SetInput(transformed);
  writer->SetFileTypeToBinary();
  writer->Update();

  std::cout << "Saving vtk..." << std::endl;
  vtkSmartPointer<vtkPolyDataWriter> writerVtk = vtkSmartPointer<vtkPolyDataWriter>::New();
  writerVtk->SetFileTypeToASCII();
  writerVtk->SetFileName(outputFileNameVtk.c_str());
  writerVtk->SetInput(transformed);
  writerVtk->Update();

  if(!GetPointNormals(transformed))
  {
      std::cout << "WARNING: Output meshes do not contain normals (likely because input file did not have normals), detection won't work!!!" << std::endl;
  }

  return EXIT_SUCCESS;
}
double_buffer( InfoStruct *recInfo, float *leadSnds[], float *lagSnds[], float *locations, float *azimuths, float *rove, float *scalesLead, float *scalesLag, float *attensLead, int nSignal )
{
FILE	*fptr;
long	seekpos = 0;
float	preloadScale = .2;
int		i, j;

char	OutFNA [MAX_FILENAME_LEN];
char	OutFNB [MAX_FILENAME_LEN];

float	temp;

int		record = recInfo->record;
int		cnt = 1;

unsigned int DEC_FACT = recInfo->decimateFactor;
unsigned int SignalPlayFlag = 0;
unsigned int signalScale = 0, Signalcnt = 0, readflag = 0;
unsigned int MAX_SIGNAL_JITTER = recInfo->max_signal_jitter;
unsigned int NUM_CARRIERS_TO_ROVE = recInfo->num_carriers;
unsigned int rove_id;
unsigned int TRIALS_TO_SHOW = 3;

long	NPTS = recInfo->buf_pts;

/* just for plotting PDR trace in real time */
long	DEC_PTS = ceil(NPTS / pow(2, DEC_FACT));
long	ONSET = ceil(recInfo->sound_onset / pow(2, DEC_FACT));
long	NPTS_totalplay = recInfo->nptsTotalPlay;
long	templ;
long	buffer_cnt=0;
float	HAB_LOC = recInfo->hab_loc;

int		src[3];
float	sf[3];

div_t	div_result;

int		loc;

/* Display output variables: */
int     t0,t1, n;
float	elapsed_time;
float	rem_time;
int		min;
float	sec, cntdown;
char	str[100] = { '\0' };
float	pdrBuffer[DEFAULT_PTS];
int		len;
float	xy[2];

/* select SS1 output */
int		ss_id, out_port;

srand( (unsigned)time( NULL ) );

/* setup session info display */
len = ceil(NPTS * (SRATE/1E3));

// was commented out - put back in on Sep 14, 2009
if (record)
{
	play0_record0(recInfo->outFN1, recInfo->outFN2);
	remove(recInfo->outFN1);
	remove(recInfo->outFN2);
	//remove(recInfo->AD_FN);
}
// end comment out


if(!S2init(0, INIT_SECONDARY, 20000))
	mexErrMsgTxt("S2init failed");

if(!APlock(200, 0))
{
	S2close();
	mexErrMsgTxt("APLock failed");
}

if(!XBlock(200, 0))
{
	APunlock(0);
	S2close();
	mexErrMsgTxt("XBlock failed");
}

trash();
dropall();

// set up buffers
allot16( PLAY_SPEC, 10);
allot16( CHA_SEQ, 10);
allot16( BUF_A1, NPTS);
allot16( BUF_A2, NPTS);
allot16( CHB_SEQ, 10);
allot16( BUF_B1, NPTS);
allot16( BUF_B2, NPTS);

// play specification list
dpush(10);
value(0);
make(0,CHA_SEQ);
make(1,CHB_SEQ);
make(2,0);
qpop16(PLAY_SPEC);

// playsequence for ChanA
dpush(10);
value(0);
make(0,BUF_A1);
make(1,1);
make(2,BUF_A2);
make(3,1);
make(4,0);
qpop16(CHA_SEQ);
// playsequence for ChanB
dpush(10);
value(0);
make(0,BUF_B1);
make(1,1);
make(2,BUF_B2);
make(3,1);
make(4,0);
qpop16(CHB_SEQ);


if (record)			// record eye signal
{
	// set up buffers
	allot16( REC_SPEC, 10);
	allot16( RECCHA_SEQ, 10);
	allot16( RECBUF_A1, NPTS);
	allot16( RECBUF_A2, NPTS);
	allot16( RECCHB_SEQ, 10);
	allot16( RECBUF_B1, NPTS);
	allot16( RECBUF_B2, NPTS);

	temp = ceil(NPTS / pow(2, DEC_FACT));
	allot16( DECBUF_A, temp);
	allot16( DECBUF_B, temp);

	// record specification list
	dpush(10);
	value(0);
	make(0,RECCHA_SEQ);
	make(1,RECCHB_SEQ);
	make(2,0);
	qpop16(REC_SPEC);

	// recordsequence for ChanA
	dpush(10);
	value(0);
	make(0,RECBUF_A1);
	make(1,1);
	make(2,RECBUF_A2);
	make(3,1);
	make(4,0);
	qpop16(RECCHA_SEQ);
	// recordsequence for ChanB
	dpush(10);
	value(0);
	make(0,RECBUF_B1);
	make(1,1);
	make(2,RECBUF_B2);
	make(3,1);
	make(4,0);
	qpop16(RECCHB_SEQ);
}

// allot and load buffers for LEAD SOUNDS
for( j=0; j<NUM_CARRIERS_TO_ROVE; j++ ) {
	allotf( BUF_LEAD(j), NPTS);
	pushf(leadSnds[j], NPTS);
	qpopf(BUF_LEAD(j));
}

// allot and load buffers for LAG SOUNDS
for( j=0; j<NUM_CARRIERS_TO_ROVE; j++ ) {
	allotf( BUF_LAG(j), NPTS);
	pushf(lagSnds[j], NPTS);
	qpopf(BUF_LAG(j));
}

// setup PD1
PD1clear(1);
PD1srate(1,SRATE);
PD1npts(1,-1);

PD1resetDSP(1,0xFFF);
dropall();
PD1clrsched(1);
PD1nstrms(1, 2, record*2);

PD1addsimp(1, IREG[0], DAC[0]);  
PD1specIB (1, IB[0],   IREG[0]);

PD1addsimp(1, IREG[1], DAC[1]);  
PD1specIB (1, IB[1],   IREG[1]);

if (record)
{
	PD1specOB (1, OB[1], ADC[1]);
	PD1specOB (1, OB[0], ADC[0]);
}

PF1freq(1,12000,0);
PF1freq(2,12000,0);

dropall();

/* set LED thresholds */
PD1setIO(1,0.01,9.99,0.01,9.99);

/* setup signal switchers */

/* SWITCH BETWEEN 8 LAG SPEAKERS (Nos. 2, 3, 4, ... 9) */
/* (NOTE: Speaker #1 is reserved for the lead sound) */

SS1clear(1); /* left SS1 (LAG) */
SS1mode(1, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
SS1select(1,0,1); /* Default Lag Output is A (Hab Location) */

// set attenuation
PA4atten(1,0); /* lead channel */
PA4atten(2,0); /* lag ch */

// ready,set,go!!
dropall();

// nothing to chanA (LEAD)
dpush(NPTS);
value(0);
qpop16(BUF_A1);

dpush(NPTS);
value(0);
qpop16(BUF_A2);
		
// nothing to chanB (LAG)
dpush(NPTS);
value(0);
qpop16(BUF_B1);
				
dpush(NPTS);
value(0);
qpop16(BUF_B2);				
			
seqplay(PLAY_SPEC);
if (record)
	seqrecord(REC_SPEC);
		
PD1arm (1);
pfireall();
PD1go (1);

do
{
 	do{}while (playseg(1)==BUF_A1);		// wait for #1 buffers to finish
	
	t0 = clock();

	SignalPlayFlag = 0;

	if(signalScale >0)
	{
		readflag = 1;
	}
	else if(readflag)
	{
		readflag = 0;
		SignalPlayFlag = 1;
	}
	

	
	/* count down to next test trial */
	cntdown = (recInfo->ISI - cnt)*(NPTS*SRATE/1E6);
	for(i=0; i<(recInfo->n_trials - Signalcnt); i++) {
		if(locations[Signalcnt+i]!=HAB_LOC)
			break;
		cntdown += (recInfo->ISI+1)*(NPTS*SRATE/1E6);

	}
		
		
	/* display session info */
	
	elapsed_time = seekpos*(SRATE/1E6);
	div_result = div( elapsed_time, 60 );
	min = div_result.quot; sec = elapsed_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.elapsed_time(1)=%i; session.elapsed_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	rem_time = NPTS_totalplay*(SRATE/1E6) - elapsed_time;
	div_result = div( rem_time, 60 );
	min = div_result.quot; sec = rem_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.rem_time(1)=%i; session.rem_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	div_result = div( cntdown, 60 );
	min = div_result.quot; sec = cntdown - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.next_test_trial(1)=%i; session.next_test_trial(2)=%.3f;",min,sec);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");
	
	
	// re-loading #1 playbuffers
	// LEAD to chanA LAG to chanB
	dropall();
	if (cnt==recInfo->ISI)
	{
		// Jitter trial presentation
		if (MAX_SIGNAL_JITTER > 0)
		{
			cnt = ( rand() % (2*MAX_SIGNAL_JITTER+1) ) - MAX_SIGNAL_JITTER; // gives a range of +/- MAX_SIGNAL_JITTER
		} else
		{
			cnt = 0;
		}
		

		loc = locations[Signalcnt];
		/* location series indicates lag speaker # (2, 3, 4, ... 9) */

	
		// set attenuation
		PA4atten(1,attensLead[loc-2]); /* lead channel */
		PA4atten(2,0); /* lag ch */

		SS1clear(1); SS1clear(2);
		if (loc < 6) {
			ss_id = 1; /* use left SS1 */
			out_port = loc - 2; /* decrement by 2 for output selection */
		}
		else {
			ss_id = 2; /* use right SS1 */
			out_port = loc - 6; /* decrement by 6 for output selection */
		}
		
		SS1mode(ss_id, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
		SS1select(ss_id,out_port,1); /* Chan B (LAG) location ( speakers A...D = 0...3 ) */


		
		/* plot a marker on trial sequence plot */
		memset(str,'\0',sizeof(str));
		n=sprintf(str,"session.trialcnt=%i; session.trialval=%10.1f;sessionPlots('Update Trial Plot');",Signalcnt+1,azimuths[loc-1]);
		mexEvalString(str);
		
		
		rove_id = rove[Signalcnt ++] - 1; /* decrement by 1 for C indexing */
		
		signalScale=scalesLead[loc-2];
		qpushf(BUF_LEAD(rove_id));
		scale(signalScale); /* always scale with first speaker scaling value */
		qpop16(BUF_A1);	

		signalScale=scalesLag[loc-2];
		qpushf(BUF_LAG(rove_id));
		scale(signalScale); /* decrement by 1 to get appropriate speaker scale value */
		qpop16(BUF_B1);

	}
	else
	{
		signalScale = 0;
		cnt++;
		dpush(NPTS);
		value(0);
		qpop16(BUF_A1);

		dpush(NPTS);
		value(0);
		qpop16(BUF_B1);	
	}

	
	if(record)
	{		// downloading  #1 recordbuffers
		qpush16 (RECBUF_A1);    
		decimate (DEC_FACT);
		make(0, SignalPlayFlag);
		make(1, loc);
		qpop16   (DECBUF_A);
		dama2disk16 (DECBUF_A, recInfo->outFN1, 1);

		qpush16 (RECBUF_B1);
		decimate (DEC_FACT);
		// plot PDR trace
		qdup();
		popf(pdrBuffer);
		// store last buffer in matlab variable for plotting
		for(i=0; i<DEC_PTS; i++) {
			memset(str,'\0',sizeof(str));
			n=sprintf(str,"session.last_buffer(%i+1)= %.5f;",i,pdrBuffer[i]);
			mexEvalString(str);
		}
		
		if(SignalPlayFlag) {
			if(locations[Signalcnt-1]==HAB_LOC) {
				mexEvalString("session.test_flag=1;");
			}
			else {
				mexEvalString("session.test_flag=Inf;");
			}
		}
		else {
			mexEvalString("session.test_flag=0;");
		}
		
		// tell sessionPlots to update trace
		mexEvalString("sessionPlots('Update Trace Plot');");
		make(0, SignalPlayFlag);
		make(1, loc);
		qpop16   (DECBUF_B);
		dama2disk16 (DECBUF_B, recInfo->outFN2, 1);
		dropall ();
		
	}
	
	/* processing time */
	
	t1=clock();
	memset(str,'\0',sizeof(str));
	n = sprintf(str,"session.proc_time = [session.proc_time %.3f];",((float) (t1-t0))/CLOCKS_PER_SEC);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");
	
	seekpos += NPTS;
	if(seekpos < NPTS_totalplay)
	{
		// wait for #2 buffers to finish
		do{}while (playseg(1)==BUF_A2);		// wait for #2 buffers to finish

     	t0=clock();
     	
		SignalPlayFlag = 0;
	
		if(signalScale >0)
		{
			readflag = 1;
		}
		else if(readflag)
		{
			readflag = 0;
			SignalPlayFlag = 1;
		}
		
	/* count down to next test trial */
	cntdown = (recInfo->ISI - cnt)*(NPTS*SRATE/1E6);
	for(i=0; i<(recInfo->n_trials - Signalcnt); i++) {
		if(locations[Signalcnt+i]!=HAB_LOC)
			break;
		cntdown += (recInfo->ISI+1)*(NPTS*SRATE/1E6);

	}
		
		
	/* display session info */
	
	elapsed_time = seekpos*(SRATE/1E6);
	div_result = div( elapsed_time, 60 );
	min = div_result.quot; sec = elapsed_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.elapsed_time(1)=%i; session.elapsed_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	rem_time = NPTS_totalplay*(SRATE/1E6) - elapsed_time;
	div_result = div( rem_time, 60 );
	min = div_result.quot; sec = rem_time - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.rem_time(1)=%i; session.rem_time(2)=%.3f;",min,sec);
	mexEvalString(str);
	div_result = div( cntdown, 60 );
	min = div_result.quot; sec = cntdown - (60*min);
	memset(str,'\0',sizeof(str));
	n=sprintf(str,"session.next_test_trial(1)=%i; session.next_test_trial(2)=%.3f;",min,sec);
	mexEvalString(str);
	mexEvalString("sessionPlots('Update Session Info');");

		// reload #2 playbuffers    LEAD to chanA LAG to chanB
		dropall();
		if (cnt==recInfo->ISI)
		{
			if (MAX_SIGNAL_JITTER > 0)
			{
				cnt = ( rand() % (2*MAX_SIGNAL_JITTER+1) ) - MAX_SIGNAL_JITTER; // gives a range of +/- MAX_SIGNAL_JITTER
			} else
			{
				cnt = 0;
			}
			
			loc = locations[Signalcnt];
			/* location series indicates lag speaker # (2, 3, 4, ... 9) */
	
			// set attenuation
			PA4atten(1,attensLead[loc-2]); /* lead channel */
			PA4atten(2,0); /* lag ch */
			
			SS1clear(1); SS1clear(2);
			if (loc < 6) {
				ss_id = 1; /* use left SS1 */
				out_port = loc - 2; /* decrement by 2 for output selection */
			}
			else {
				ss_id = 2; /* use right SS1 */
				out_port = loc - 6; /* decrement by 6 for output selection */
			}
		
			SS1mode(ss_id, QUAD_2_1); /* inputs 1, 3, 5, 7 => outputs A,B,C,D */
			SS1select(ss_id,out_port,1); /* Chan B (LAG) location ( speakers A...D = 0...3 ) */
		
			/* plot a marker on trial sequence plot */
			memset(str,'\0',sizeof(str));
			n=sprintf(str,"session.trialcnt=%i; session.trialval=%10.1f;sessionPlots('Update Trial Plot');",Signalcnt+1,azimuths[loc-1]);
			mexEvalString(str);

			rove_id = rove[Signalcnt ++] - 1; /* decrement by 1 for C indexing */
			
			signalScale=scalesLead[loc-2];
			qpushf(BUF_LEAD(rove_id));
			scale(signalScale); /* always scale with first speaker scaling value */
			qpop16(BUF_A2);	
	
			signalScale=scalesLag[loc-2];
			qpushf(BUF_LAG(rove_id));
			scale(signalScale); /* decrement by 1 to get appropriate speaker scale value */
			qpop16(BUF_B2);

		}
		else
		{
			signalScale = 0;
			cnt++;
			dpush(NPTS);
			value(0);;
			qpop16(BUF_A2);

			dpush(NPTS);
			value(0);
			qpop16(BUF_B2);
		}
		
		
		if (record)
		{		// download #2 recordbuffers
			qpush16 (RECBUF_A2);    
			decimate (DEC_FACT);
			make(0,SignalPlayFlag);
			make(1,loc);
			qpop16	(DECBUF_A);
			dama2disk16 (DECBUF_A, recInfo->outFN1, 1);

			qpush16 (RECBUF_B2);
			decimate (DEC_FACT);
			// plot PDR trace
			qdup();
			popf(pdrBuffer);
			// store last buffer in matlab variable for plotting
			for(i=0; i<DEC_PTS; i++) {
				memset(str,'\0',sizeof(str));
				n=sprintf(str,"session.last_buffer(%i+1)= %.5f;",i,pdrBuffer[i]);
				mexEvalString(str);
			}

			if(SignalPlayFlag) {
				if(locations[Signalcnt-1]==HAB_LOC) {
					mexEvalString("session.test_flag=1;");
				}
				else {
					mexEvalString("session.test_flag=Inf;");
				}
			}
			else {
				mexEvalString("session.test_flag=0;");
			}

			// tell sessionPlots to update trace
			mexEvalString("sessionPlots('Update Trace Plot');");
			make(0,SignalPlayFlag);
			make(1,loc);
			qpop16   (DECBUF_B);
			dama2disk16 (DECBUF_B, recInfo->outFN2, 1);
			dropall ();
		
		}

		if (playseg(1) !=BUF_A1)
		{
			PD1stop(1);
			mexPrintf("got to %d percent of the way\n",seekpos/NPTS_totalplay);
			mexErrMsgTxt(" APcard too slow? or outFNs incorrect?");
		}

		/* processing time */
	
		t1=clock();
		memset(str,'\0',sizeof(str));
		n = sprintf(str,"session.proc_time = [session.proc_time %.3f];",((float) (t1-t0))/CLOCKS_PER_SEC);
		mexEvalString(str);
		mexEvalString("sessionPlots('Update Session Info');");
		
	    seekpos += NPTS;
	}
	if (Signalcnt > nSignal)
		Signalcnt = 0;

} while(seekpos < NPTS_totalplay);

do{}while (playseg(1)==BUF_A1);		/* wait for last 2 buffers to finish */
do{}while (playseg(1)==BUF_A2);



PA4mute(1);
PA4mute(2);

PD1stop(1);
PD1clrIO(1);
PD1clear(1);

mexEvalString("sessionPlots('Finish Session');");

trash();
dropall();

APunlock(0);
XBunlock(0);
S2close();

}