コード例 #1
0
ファイル: line2.cpp プロジェクト: arciem/LibArciem
bool line2::intersects_with_line(line2 const &l, point2& ip, bool line_segments) const
{
	double x1 = p1.x;
	double y1 = p1.y;
	double x2 = p2.x;
	double y2 = p2.y;
	double x3 = l.p1.x;
	double y3 = l.p1.y;
	double x4 = l.p2.x;
	double y4 = l.p2.y;
	
	double const TOL = 0.0001;
	
    double q1 = (x1 - x2) * (y4 - y3) - (y1 - y2) * (x4 - x3);
    double q2 = (x3 - x4) * (y2 - y1) - (y3 - y4) * (x2 - x1);
	
	// Are the lines parallel?
	if(fabs(q1) < TOL) return false;
	
	// Compute the intersection parameters
	double u1 = ((x1 - x3) * (y4 - y3) - (y1 - y3) * (x4 - x3)) / q1;
	double u2 = ((x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1)) / q2;

	// Do the lines need to intersect within their finite length?
	if(line_segments) {
		if(u1 < -TOL || u1 > 1.0 + TOL || u2 < -TOL || u2 > 1.0 + TOL) return false;
	}
	
	ip.x = denormalize(u1, p1.x, p2.x);
	ip.y = denormalize(u1, p1.y, p2.y);
	
	return true;
}
コード例 #2
0
ファイル: gmmreg_base.cpp プロジェクト: alxio/gmmreg
void gmmreg_base::denormalize_all() {
  if (b_normalize) {
    denormalize(transformed_model, scene_centroid, scene_scale);
    denormalize(model, scene_centroid, scene_scale);
    denormalize(scene, scene_centroid, scene_scale);
  }
}
コード例 #3
0
ファイル: intrinsic.cpp プロジェクト: oakfr/omni3d
/* constructor
 */
Intrinsic::Intrinsic (int w, int h, double focal, double c1, double c2, double k1, double k2, double k3, double k4, double k5, double w_mm, double h_mm) 
{
	f = focal;
	width = w;
	height = h;
	cc = Vec2d(c1,c2);
	CC = denormalize(cc);
	kc[0] = k1; kc[1] = k2; kc[2] = k3; kc[3] = k4; kc[4] = k5;
	pixel_width_mm = w_mm;
	pixel_height_mm = h_mm;
	double fov = toRadians(70.0); // estimated Ladybug FOV, given the fact that 5 cameras cover 360 degrees + overlap
	pixel_angle = (double)fov / height; // radians per pixel
	dist_model = POLYNOMIAL_DISTORTION;
	value = 0.0;
	Vec2d FF = denormalize(Vec2d(f,f));
	focal_x = FF[0];
	focal_y = FF[1];

	Vec2d a = Vec2d( -0.5, -(double)h/(2.0*w) );
	Vec2d b = Vec2d(  0.5, -(double)h/(2.0*w) );
	Vec2d c = Vec2d(  0.5,  (double)h/(2.0*w) );
	Vec2d d = Vec2d( -0.5,  (double)h/(2.0*w) );

	LEFT =  Edge2D(a, d, 0);
	RIGHT = Edge2D(b, c, 0);
	TOP =   Edge2D(c, d, 0);
	BOTTOM = Edge2D(a, b, 0);
}
コード例 #4
0
ファイル: intrinsic.cpp プロジェクト: oakfr/omni3d
/* constructor
 */
Intrinsic::Intrinsic (int id, int w, int h, double focal, double c1, double c2, double v, double w_mm, double h_mm) 
{
	_id = id;
	width = w;
	height = h;
	f = focal;
	cc = Vec2d(c1,c2);
	CC = denormalize(cc);
	value = v;
	dist_model = SPHERICAL_DISTORTION;
	kc[0] = 0.0; kc[1] = 0.0; kc[2] = 0.0; kc[3] = 0.0; kc[4] = 0.0;
	Vec2d FF = denormalize(Vec2d(f,f));
	focal_x = 345.36; //5*FF[0];
	focal_y = 345.36; //FF[1];
	pixel_width_mm = w_mm;
	pixel_height_mm = h_mm;	
	double fov = toRadians(70.0); // estimated Ladybug FOV, given the fact that 5 cameras cover 360 degrees + overlap
	pixel_angle = (double)fov / width; // radians per pixel

	Vec2d a = Vec2d( -0.5, -(double)h/(2.0*w) );
	Vec2d b = Vec2d(  0.5, -(double)h/(2.0*w) );
	Vec2d c = Vec2d(  0.5,  (double)h/(2.0*w) );
	Vec2d d = Vec2d( -0.5,  (double)h/(2.0*w) );

	LEFT =  Edge2D(a, d, 0);
	RIGHT = Edge2D(b, c, 0);
	TOP =   Edge2D(c, d, 0);
	BOTTOM = Edge2D(a, b, 0);
}
コード例 #5
0
ファイル: line2.cpp プロジェクト: arciem/LibArciem
line2 line2::interpolate(line2 const& l, double fraction) const
{
	return line2(
		denormalize(fraction, x1(), l.x1()),
		denormalize(fraction, y1(), l.y1()),
		denormalize(fraction, x2(), l.x2()),
		denormalize(fraction, y2(), l.y2())
	);
}
コード例 #6
0
ファイル: emfloat.c プロジェクト: ABratovic/open-watcom-v2
/*********************
** RoundInternalFPF **
**********************
** Round an internal-representation number.
** The kind of rounding we do here is simplest...referred to as
** "chop".  "Extraneous" rightmost bits are simply hacked off.
*/
void RoundInternalFPF(InternalFPF *ptr)
{
/* int i; */

if (ptr->type == IFPF_IS_NORMAL ||
        ptr->type == IFPF_IS_SUBNORMAL)
{
        denormalize(ptr, MIN_EXP);
        if (ptr->type != IFPF_IS_ZERO)
        {
        
                /* clear the extraneous bits */
                ptr->mantissa[3] &= 0xfff8;
/*              for (i=4; i<INTERNAL_FPF_PRECISION; i++)
                {
                        ptr->mantissa[i] = 0;
                }
*/
                /*
                ** Check for overflow
                */
                if ((unsigned)ptr->exp > MAX_EXP)
                {
                        SetInternalFPFInfinity(ptr, ptr->sign);
                }
        }
}
return;
}
コード例 #7
0
long fx_numeric_field::change_on_digit(int sign)
{
    FXString txt = getText();
    int pos = getCursorPos();

    int pow_exp, dot_pos;
    int norm = get_normalized_int (txt.text(), pow_exp, dot_pos);

    if (dot_pos < 0) return 0;

    int pos_exp = dot_pos - pos;
    if (pos_exp < 0)
        pos_exp ++;
    int inc_abs = ipow10 (pos_exp + pow_exp);

    norm += sign * inc_abs;

    FXString new_txt = denormalize (norm, pow_exp, dot_pos);
    int new_pos = dot_pos - pos_exp;
    if (pos_exp < 0)
        new_pos ++;

    setText(new_txt);
    setCursorPos(new_pos);

    if (target)
        target->tryHandle(this, FXSEL(SEL_CHANGED,message), (void*)new_txt.text());

    return 1;
}
コード例 #8
0
void SignalProcessorAudioProcessor::sendSignalLevelMsg() {
    if (sendBinaryUDP) {
        signal.set_signallevel(denormalize(inputSensitivity * signalInstantEnergy));
        signal.SerializeToArray(dataArrayLevel, signal.GetCachedSize());
        udpClientSignalLevel.send(dataArrayLevel, signal.GetCachedSize());
    }
    if (sendOSC) {
        //Example of an OSC signal level message : SIGLVL1/0.23245
        oscOutputStream->Clear();
        *oscOutputStream << osc::BeginBundleImmediate
        << osc::BeginMessage( "SIGLVL" )
        << channel << "/"
        << denormalize(inputSensitivity * signalInstantEnergy) << osc::EndMessage
        << osc::EndBundle;
        oscTransmissionSocket.Send( oscOutputStream->Data(), oscOutputStream->Size() );
    }
}
コード例 #9
0
ファイル: BSPOctTree.cpp プロジェクト: RoyLab/CSGBoolean
void NormalMesh::DenormalizeCoord()
{
    assert(m_bCoordNormalized);

    m_bCoordNormalized = false;
    mCurAABB = mOrigAABB;

	auto center = mTransAABB.Center();
	auto scale = mTransAABB.Diagonal();

	for (auto &v: mVertex)
		v = denormalize(v, center, scale);
}
コード例 #10
0
ファイル: intrinsic.cpp プロジェクト: oakfr/omni3d
/* print out the intrinsic parameters
 */
void Intrinsic::print()
{
	Vec2d center;
	
	switch (dist_model) {
	case SPHERICAL_DISTORTION:
		printf("%d SPHERICAL wxh: %dx%d focal: %f center: %.4f,%.4f\n",_id,width,height,f,cc[0],cc[1]);
		center = denormalize(cc);
		printf("center(pixels): %.2f,%.2f  focal(pixels): %.2f,%.2f\n",center[0],center[1],focal_x,focal_y);
	default:
		break;
	}
}
コード例 #11
0
ファイル: intrinsic.cpp プロジェクト: oakfr/omni3d
/* constructor
 */
Intrinsic::Intrinsic () 
{
	f=0.0; 
	cc=Vec2d(0,0); 
	width = height = 1;
	CC = denormalize(cc);
	kc[0] = kc[1] = kc[2] = kc[3] = kc[4] = 0.0; 
	pixel_width_mm = 0; pixel_height_mm = 0;
	value = 0.0;
	dist_model = POLYNOMIAL_DISTORTION;
	focal_x = focal_y = 0;
	pixel_angle = 0.0;
};
コード例 #12
0
ファイル: env.c プロジェクト: grandhuit/wine-patched
/******************************************************************************
 *  RtlDeNormalizeProcessParams  [NTDLL.@]
 */
PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams( RTL_USER_PROCESS_PARAMETERS *params )
{
    if (params && (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED))
    {
        denormalize( params, &params->CurrentDirectory.DosPath.Buffer );
        denormalize( params, &params->DllPath.Buffer );
        denormalize( params, &params->ImagePathName.Buffer );
        denormalize( params, &params->CommandLine.Buffer );
        denormalize( params, &params->WindowTitle.Buffer );
        denormalize( params, &params->Desktop.Buffer );
        denormalize( params, &params->ShellInfo.Buffer );
        denormalize( params, &params->RuntimeInfo.Buffer );
        params->Flags &= ~PROCESS_PARAMS_FLAG_NORMALIZED;
    }
    return params;
}
コード例 #13
0
void SignalProcessorAudioProcessor::sendSignalInstantValMsg(float val) {
    if (sendBinaryUDP) {
        instantVal.set_signalinstantval(instantSigValGain * val);
        instantVal.SerializeToArray(dataArrayInstantVal, instantVal.GetCachedSize());
        udpClientSignalInstantVal.send(dataArrayInstantVal, instantVal.GetCachedSize());
    }
    if (sendOSC) {
        //Example of an OSC signal level message : SIGINSTVAL1/0.23245
        oscOutputStream->Clear();
        *oscOutputStream << osc::BeginBundleImmediate
        << osc::BeginMessage( "SIGINSTVAL" )
        << channel << "/"
        << denormalize(inputSensitivity * val) << osc::EndMessage
        << osc::EndBundle;
        oscTransmissionSocket.Send( oscOutputStream->Data(), oscOutputStream->Size() );
    }
}
コード例 #14
0
    void CPDNRigid<T, D>::run()
    {
        size_t iter_num = 0;
        T e_tol = 10 + _e_tol;
        T e = 0;
        
        normalize();
        initialization();

        if (_vision)
        {
            RenderThread<T, D>::instance()->updateModel(_model);
            RenderThread<T, D>::instance()->updateData(_data);
            RenderThread<T, D>::instance()->startThread();
        }

        while (iter_num < _iter_num && e_tol > _e_tol && _paras._sigma2 > 10 * _v_tol)
        {

            e_step();
            
            T old_e = e;
            e = energy();
            e += _paras._lambda/2 * (_paras._W.transpose()*_G*_paras._W).trace();
            e_tol = abs((e - old_e) / e);

            m_step();

            if (_vision == true)
                RenderThread<T, D>::instance()->updateModel(_T);

            iter_num ++;	
        }
        
        correspondences();
        updateModel();
        denormalize();
        RenderThread<T, D>::instance()->cancel();	
    }
コード例 #15
0
ファイル: KnobGuiValue.cpp プロジェクト: JamesLinus/Natron
/*
 FROM THE OFX SPEC:
 
 * kOfxParamCoordinatesNormalised is OFX > 1.2 and is used ONLY for setting defaults
 
 These new parameter types can set their defaults in one of two coordinate systems, the property kOfxParamPropDefaultCoordinateSystem. Specifies the coordinate system the default value is being specified in.
 
 * kOfxParamDoubleTypeNormalized* is OFX < 1.2 and is used ONLY for displaying the value: get/set should always return the normalized value:
 
 To flag to the host that a parameter as normalised, we use the kOfxParamPropDoubleType property. Parameters that are so flagged have values set and retrieved by an effect in normalized coordinates. However a host can choose to represent them to the user in whatever space it chooses.
 
 Both properties can be easily supported:
 - the first one is used ONLY when setting the *DEFAULT* value
 - the second is used ONLY by the GUI
 */
void
KnobGuiValue::valueAccordingToType(bool doNormalize,
                                    int dimension,
                                    double* value)
{
    if ((dimension != 0) && (dimension != 1)) {
        return;
    }
    
    ValueIsNormalizedEnum state = getNormalizationPolicy(dimension);
    
    if (state != eValueIsNormalizedNone) {
        KnobPtr knob = _imp->getKnob();
        if (knob) {
            SequenceTime time = knob->getCurrentTime();
            if (doNormalize) {
                normalize(dimension, time, value);
            } else {
                denormalize(dimension, time, value);
            }
        }
    }
    
}
コード例 #16
0
ファイル: import.c プロジェクト: swhobbit/UUPC
static KWBoolean
advancedFS(const char *path)
{
   static char UUFAR cache[256] = "";  /* Initialize cache to zeroes  */
   char driveInfo[FILENAME_MAX];
   char fsType[128];
   BOOL result;
   KWBoolean cacheable;
   DWORD maxNameLength;
   KWBoolean longNamesSupported;

   if (!path || *path == '\0')         /* Name not supplied          */
   {                                   /* Yes --> Abort              */
      printmsg(0,"advancedFS: Missing path name");
      panic();
      return KWFalse;
   }
   else if (isalpha(*path) && (path[1] == ':'))
   {                                   /* It's a local drive          */

      printmsg(5, "advancedFS: it's a drive letter");
      strncpy(driveInfo, path, 3);
      cacheable = KWTrue;
      toupper( driveInfo[0] );      /* Normalize upper case for cache */
      driveInfo[3] = '\0';          /* Terminate drive string data    */

      switch(cache[ (unsigned char) driveInfo[0] ])
      {
         case CACHE_LONG_NAME_SUPPORT:
            return KWTrue;

         case CACHE_SHORT_NAME_ONLY:
            return KWFalse;

         default:
            break;
      }

   }
   else /* It's a shared drive... parse out the share name and ask */
   {
      int len;
      char *shareNameEnd;

      if (strncmp(path, "//", 2) != 0) /* Just double-checking */
         return KWFalse;  /* Don't know what it is, don't want to know */

      shareNameEnd = strchr(path + 2, '/');
      if (!shareNameEnd)  /* Probably bad:  server name only */
         return KWFalse;

      shareNameEnd = strchr(shareNameEnd + 1, '/');
      if (shareNameEnd)
      {
         /* Copy the server and share name, including the trailing slash */
         len = shareNameEnd - path + 1;
         memcpy(driveInfo, path, len);
         driveInfo[len] = '\0';
         shareNameEnd = driveInfo;

/*--------------------------------------------------------------------*/
/* On network drives, the GetVolumeInformation call fails unless      */
/* we use back slashes.                                               */
/*--------------------------------------------------------------------*/

         denormalize( shareNameEnd );
      } else
         return KWFalse;

      cacheable = KWFalse;

   } /* else */

/*--------------------------------------------------------------------*/
/*            We've got the drive letter, query its status            */
/*--------------------------------------------------------------------*/

   result = GetVolumeInformation(driveInfo,
                                 NULL,
                                 0,
                                 NULL,
                                 &maxNameLength,
                                 NULL,
                                 fsType,
                                 sizeof fsType);

   if (!result)
   {
      DWORD dwError = GetLastError();
      printmsg(0, "advancedFS: Unable to query file system for %s", driveInfo);
      printNTerror("GetVolumeInformation", dwError);
      panic();
   }

   if (maxNameLength > 12)
      longNamesSupported = KWTrue;
   else
      longNamesSupported = KWFalse;

   if ( cacheable )
      cache[ (unsigned char) driveInfo[0] ] = (char)
               (longNamesSupported ? CACHE_LONG_NAME_SUPPORT :
                                    CACHE_SHORT_NAME_ONLY);

   printmsg(4,"advancedFS: File system \"%s\" is type \"%s\""
              " with maximum name length %d",
               driveInfo,
               fsType,
               maxNameLength);

   return longNamesSupported;

} /* advancedFS for WIN32 */
コード例 #17
0
ファイル: tspsolver.cpp プロジェクト: jue-jiang/tspsg
/*!
 * \brief Solves the given task.
 * \param numCities Number of cities in the task.
 * \param task The matrix of city-to-city travel costs.
 * \return Pointer to the root of the solution tree.
 *
 * \todo TODO: Comment the algorithm.
 */
SStep *CTSPSolver::solve(int numCities, const TMatrix &task)
{
    if (numCities < 3)
        return NULL;

QMutexLocker locker(&mutex);
    cleanup();
    canceled = false;
    locker.unlock();

    nCities = numCities;

SStep *step = new SStep();
    step->matrix = task;
    // We need to distinguish the values forbidden by the user
    // from the values forbidden by the algorithm.
    // So we replace user's infinities by the maximum available double value.
    normalize(step->matrix);
#ifdef DEBUG
    qDebug() << step->matrix;
#endif // DEBUG
    step->price = align(step->matrix);
    root = step;

SStep *left, *right;
int nRow, nCol;
bool firstStep = true;
double check = INFINITY;
    total = 0;
    while (route.size() < nCities) {
        step->alts = findCandidate(step->matrix,nRow,nCol);

        while (hasSubCycles(nRow,nCol)) {
#ifdef DEBUG
            qDebug() << "Forbidden: (" << nRow << ";" << nCol << ")";
#endif // DEBUG
            step->matrix[nRow][nCol] = INFINITY;
            step->price += align(step->matrix);
            step->alts = findCandidate(step->matrix,nRow,nCol);
        }

#ifdef DEBUG
        qDebug() /*<< step->matrix*/ << "Selected: (" << nRow << ";" << nCol << ")";
        qDebug() << "Alternate:" << step->alts;
        qDebug() << "Step price:" << step->price << endl;
#endif // DEBUG

        locker.relock();
        if ((nRow == -1) || (nCol == -1) || canceled) {
            if (canceled && cc)
                cleanup();
            return NULL;
        }
        locker.unlock();

        // Route with (nRow,nCol) path
        right = new SStep();
        right->pNode = step;
        right->matrix = step->matrix;
        for (int k = 0; k < nCities; k++) {
            if (k != nCol)
                right->matrix[nRow][k] = INFINITY;
            if (k != nRow)
                right->matrix[k][nCol] = INFINITY;
        }
        right->price = step->price + align(right->matrix);
        // Forbid the selected route to exclude its reuse in next steps.
        right->matrix[nCol][nRow] = INFINITY;
        right->matrix[nRow][nCol] = INFINITY;

        // Route without (nRow,nCol) path
        left = new SStep();
        left->pNode = step;
        left->matrix = step->matrix;
        left->matrix[nRow][nCol] = INFINITY;
        left->price = step->price + align(left->matrix);

        step->candidate.nRow = nRow;
        step->candidate.nCol = nCol;
        step->plNode = left;
        step->prNode = right;

        // This matrix is not used anymore. Restoring infinities back.
        denormalize(step->matrix);

        if (right->price <= left->price) {
            // Route with (nRow,nCol) path is cheaper
            step->next = SStep::RightBranch;
            step = right;
            route[nRow] = nCol;
            emit routePartFound(route.size());
            if (firstStep) {
                check = left->price;
                firstStep = false;
            }
        } else {
            // Route without (nRow,nCol) path is cheaper
            step->next = SStep::LeftBranch;
            step = left;
            QCoreApplication::processEvents();
            if (firstStep) {
                check = right->price;
                firstStep = false;
            }
        }
        total++;
    }

    mayNotBeOptimal = (check < step->price);

    return root;
}
コード例 #18
0
ファイル: point2.hpp プロジェクト: arciem/LibArciem
	point2 interpolate(point2 const& p, double fraction) const {
		return point2( denormalize(fraction, x, p.x), denormalize(fraction, y, p.y) ); }
コード例 #19
0
ファイル: logger.c プロジェクト: swhobbit/UUPC
void openlog(const char *log)
{
   char *newLogName;
   FILE *stream = NULL;
   int saveDebuglevel = debuglevel;

/*--------------------------------------------------------------------*/
/*                             Housekeeping                           */
/*--------------------------------------------------------------------*/

   if (E_logdir == NULL)         /* We DID call configure, didn't we? */
      panic();                   /* Ooopps --> I guess not.           */

    MKDIR(E_logdir);             /* Make sure directory exists!       */

/*--------------------------------------------------------------------*/
/*       If we already had a log file, spin it off and copy it        */
/*--------------------------------------------------------------------*/

   if (permanentLogName != NULL)
      copylog();

/*--------------------------------------------------------------------*/
/*                Create the final log name for later                 */
/*--------------------------------------------------------------------*/

   if ((log != NULL) || (permanentLogName == NULL))
   {
      char fname[FILENAME_MAX];
      char *newName = (char*) ((log == NULL) ? compilen : log);
      char *period = strchr(newName, '.');

      mkfilename(fname, E_logdir, newName);

      if (period == NULL)
         strcat(fname, ".log");

      newLogName = newstr(fname);
   }
   else
      newLogName = permanentLogName;

/*--------------------------------------------------------------------*/
/*                   Create temporary log file name                   */
/*--------------------------------------------------------------------*/

   if (bflag[F_MULTITASK])
   {
      char fname[FILENAME_MAX];
      short retries = 15;

      while ((stream == NULL) && retries--)
      {
         mkdirfilename(fname, E_logdir, "log");
                                    /* Get a temp log file name       */

         denormalize(fname);
         stream = fopen(fname, "a+");

         if (stream == NULL)
            printerr(fname);

      } /* while */

      currentLogName = newstr(fname);
                                 /* Save name we log to for posterity */

   } /* if */
   else {
      currentLogName = newLogName;  /* Log directly to true log file  */
      stream  = FOPEN(currentLogName , "a",TEXT_MODE);
                              /* We append in case we are not in
                                 multitask mode and we do not want
                                 to clobber the real log!             */
   } /* else */

   if (stream == NULL)
   {
      printmsg(0,"Cannot open any log file!");
      panic();
   }

   full_log_file_name = currentLogName;
                                    /* Tell printmsg() what our log
                                       file name is                   */
   logfile  = stream;               /* And of the the stream itself   */

/*--------------------------------------------------------------------*/
/*               Request the copy function be run later               */
/*--------------------------------------------------------------------*/

   if (permanentLogName == NULL)
      atexit(copylog);

/*--------------------------------------------------------------------*/
/*    Tag the new log file with the current time and program date.    */
/*--------------------------------------------------------------------*/

   debuglevel = 0;                  /* Insure we time stamp          */

   printmsg(-1,"%s: %s %s (%s %s)",
            compilen, compilep, compilev, compiled, compilet);
   debuglevel = saveDebuglevel;

   if (ferror(logfile))
   {
      printerr(currentLogName);
      panic();
   }

/*--------------------------------------------------------------------*/
/*       Save log file name for latter reference and as a flag        */
/*       that we were called                                          */
/*--------------------------------------------------------------------*/

   permanentLogName = newLogName;

} /* openlog */
コード例 #20
0
void SignalProcessorAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{

    //////////////////////////////////////////////////////////////////
    // MIDI processing takes place here !

    
    //////////////////////////////////////////////////////////////////
    // Audio processing takes place here !
    
    // If the signal is defined by the user as mono, no need to check the second channel
    int numberOfChannels = (monoStereo==false) ? 1 : getNumInputChannels();
    for (int channel = 0; channel < numberOfChannels; channel++)
    {
        const float* channelData = buffer.getReadPointer (channel);

        //Only read one value out of nbOfSamplesToSkip, it's faster this way
        for (int i=0; i<buffer.getNumSamples(); i+=nbOfSamplesToSkip) {
            
            // Signal average: The objective is to get an average of the signal's amplitude -> use the absolute value
            signalSum += std::abs(channelData[i]);
            // Note: Possible optimization to be done using the mean square of the vector.
            // extern void vDSP_measqv
            
        }

        // Instant signal value
        if (sendSignalInstantVal == true) {
            for (int i=0; i<buffer.getNumSamples(); i+=1) {
                if (instantSigValNbOfSamplesSkipped >= instantSigValNbOfSamplesToSkip) {
                    sendSignalInstantValMsg(channelData[i]);
                    instantSigValNbOfSamplesSkipped = 0;
                }
                else {
                    instantSigValNbOfSamplesSkipped += 1;
                }
            }
        }
    }
    
    nbBufValProcessed += buffer.getNumSamples();
    samplesSinceLastTimeInfoTransmission += buffer.getNumSamples();
    
    if (sendFFT == true) {
        // For the FFT, only check the left channel (mono), it's not very useful the work twice. This could be changed in the future if a case where this is needed were to appear
        for (int i=0; i<buffer.getNumSamples(); i+=1) {
            // Move the available buffer in the processed data buffer (for FFT)
            *(fftBuffer + fftBufferIndex) = *(buffer.getReadPointer(0) + i);
            fftBufferIndex += 1;
            if (fftBufferIndex >= N) {
                computeFFT();
            }
        }
    }
    
    //Must be calculated before the instant signal, or else the beat effect will be minimized
    signalAverageEnergy = denormalize(((signalAverageEnergy * (averageEnergyBufferSize-1)) + signalInstantEnergy) / averageEnergyBufferSize);
    signalInstantEnergy = signalSum / (averagingBufferSize * numberOfChannels);

    if (sendImpulse == true) {
        
        // Fade the beat detection image (variable used by the editor)
        if (beatIntensity > 0.1) {
            beatIntensity = std::max(0.1, beatIntensity - 0.05);
        }
        else {
            beatIntensity = 0.1;
        }
        
    }
    else {
        beatIntensity = 0;
    }
    
    // If the instant signal energy is thresholdFactor times greater than the average energy, consider that a beat is detected
    if (signalInstantEnergy > signalAverageEnergy*thresholdFactor) {
        
        //Set the new signal Average Energy to the value of the instant energy, to avoid having bursts of false beat detections
        signalAverageEnergy = signalInstantEnergy;
        
        if (sendImpulse == true) {
            //Send the impulse message (which was pre-generated earlier)
            sendImpulseMsg();
        }
    }
    
    if (nbBufValProcessed >= averagingBufferSize) {
        if (sendSignalLevel == true) {
            sendSignalLevelMsg();
        }
        
        nbBufValProcessed = 0;
        signalSum = 0;
    }
    
    if (samplesSinceLastTimeInfoTransmission >= timeInfoCycle) {
        // Ask the host for the current time
        if (sendTimeInfo == true) {
            sendTimeinfoMsg();
        }
        else {
            // Don't send the current time, set the GUI info to a default value
            lastPosInfo.resetToDefault();
        }
        samplesSinceLastTimeInfoTransmission = 0;
    }
}