<commit_before>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2016 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#include "ModelingTools.hpp"
#include "SimulationTools.hpp"
#include "CommonSMC.hpp"
#include "ControlSensor.hpp"
#include "FirstOrderR_helpers.hpp"

#include <string>

void CommonSMC::initialize(const NonSmoothDynamicalSystem & nsds, const Simulation & s)
{
  if (!_Csurface && _pluginhName.empty())
  {
    RuntimeException::selfThrow("CommonSMC::initialize - you have to set either _Csurface or h(.) before initializing the Actuator");
  }
  else
  {
    if (_Csurface && !_u)
      _u.reset(new SiconosVector(_Csurface->size(0), 0));

    Actuator::initialize(nsds,s);
  }
  // We can only work with FirstOrderNonLinearDS, FirstOrderLinearDS and FirstOrderLinearTIDS
  // We can use the Visitor mighty power to check if we have the right type
  SP::DynamicalSystem DS = _sensor->getDS();
  Type::Siconos dsType;
  dsType = Type::value(*DS);

  // create the DS for the controller
  // if the DS we use is different from the DS we are controlling
  // when we want for instant to see how well the controller behaves
  // if the plant model is not exact, we can use the setSimulatedDS
  // method
  if (dsType == Type::FirstOrderNonLinearDS)
  {
    _DS_SMC.reset(new FirstOrderNonLinearDS(*(std11::static_pointer_cast<FirstOrderNonLinearDS>(DS))));
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderNonLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else if (dsType == Type::FirstOrderLinearDS)
  {
    _DS_SMC.reset(new FirstOrderLinearDS(*(std11::static_pointer_cast<FirstOrderLinearDS>(DS))));
    std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setComputebFunction(NULL);
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else if (dsType == Type::FirstOrderLinearTIDS)
  {
    _DS_SMC.reset(new FirstOrderLinearTIDS(*(std11::static_pointer_cast<FirstOrderLinearTIDS>(DS))));
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else
  {
    RuntimeException::selfThrow("LinearSMC is not yet implemented for system of type" + dsType);
  }
  // Get the dimension of the output
  // XXX What if there is more than one sensor ...
  double t0 = nsds.t0();
  double T = nsds.finalT() + _td->currentTimeStep(0);
  // create the SMC Model
  _nsdsSMC.reset(new NonSmoothDynamicalSystem(t0, T));
  // Set up the simulation
  _simulationSMC.reset(new TimeStepping(_td));

  unsigned int sDim = _u->size();
  // create the interaction
  if (!_plugingName.empty())
  {
    if (_pluginhName.empty())
      RuntimeException::selfThrow("LinearSMC::initialize - the Controller has a function g set but _pluginhName is not set\n You must supply a function to compute y=h(x,...)");
    if (!_pluginJacgxName.empty()) // Is the relation the most generic NL one ?
    {
      _relationSMC.reset(new FirstOrderNonLinearR());
      _relationSMC->setComputeJacgxFunction(SSLH::getPluginName(_pluginJacgxName), SSLH::getPluginFunctionName(_pluginJacgxName));

      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
      if (_pluginJachlambdaName.empty() && !_D)
        _D.reset(new SimpleMatrix(sDim, sDim, 0));
      FirstOrderRHelpers::JachlambdaSetter(*_relationSMC, _D, _pluginJachlambdaName);

    }
    else if (!_pluginJachlambdaName.empty() || _D) // Type2R ?
    {
      _relationSMC.reset(new FirstOrderType2R());
      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
      FirstOrderRHelpers::JachlambdaSetter(*_relationSMC, _D, _pluginJachlambdaName);
    }
    else // Type1R
    {
      _relationSMC.reset(new FirstOrderType1R());
      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
    }

    _relationSMC->setComputehFunction(SSLH::getPluginName(_pluginhName), SSLH::getPluginFunctionName(_pluginhName));
    _relationSMC->setComputegFunction(SSLH::getPluginName(_plugingName), SSLH::getPluginFunctionName(_plugingName));

    if (_computeResidus)
    {
      _simulationSMC->setComputeResiduY(true);
      _simulationSMC->setComputeResiduR(true);
      _simulationSMC->setUseRelativeConvergenceCriteron(false);
    }
  }
  else
  {
    if (!_plugineName.empty())
    {
      _relationSMC.reset(new FirstOrderLinearR(_Csurface, _B));
      _relationSMC->setComputeEFunction(SSLH::getPluginName(_plugineName), SSLH::getPluginFunctionName(_plugineName));
    }
    else
    {
      _relationSMC.reset(new FirstOrderLinearTIR(_Csurface, _B));
    }
      std11::static_pointer_cast<FirstOrderLinearTIR>(_relationSMC)->setDPtr(_D);
  }

  // _nsLawSMC and the OSNSP can be defined in derived classes, like twisting
  if (!_nsLawSMC)  _nsLawSMC.reset(new RelayNSL(sDim, -_alpha, _alpha));
  if (!_OSNSPB_SMC) _OSNSPB_SMC.reset(new Relay(_numericsSolverId));

  _interactionSMC.reset(new Interaction(_nsLawSMC, _relationSMC));

  if (dsType == Type::FirstOrderNonLinearDS)
  {
    _integratorSMC.reset(new EulerMoreauOSI(_thetaSMC));
  }
  else
  {
    _integratorSMC.reset(new ZeroOrderHoldOSI());
  }

  _nsdsSMC->insertDynamicalSystem(_DS_SMC);
  _nsdsSMC->setName(_DS_SMC, "plant_SMC");
  _nsdsSMC->link(_interactionSMC, _DS_SMC);
  _nsdsSMC->setControlProperty(_interactionSMC, true);
  _nsdsSMC->topology()->setName(_interactionSMC, "Sgn_SMC");
  _simulationSMC->setName("linear sliding mode controller simulation");
  _simulationSMC->associate(_integratorSMC, _DS_SMC);
  // OneStepNsProblem
  _OSNSPB_SMC->numericsSolverOptions()->dparam[0] = _precision;
  //    std::cout << _OSNSPB_SMC->numericsSolverOptions()->dparam[0] <<std::endl;
  _simulationSMC->insertNonSmoothProblem(_OSNSPB_SMC);
  // Finally we can initialize everything ...
  _simulationSMC->associate(_integratorSMC,_DS_SMC);

  // _SMC->setSimulation(_simulationSMC);
  // _SMC->initialize();

  // Handy
  _eventsManager = _simulationSMC->eventsManager();
  _lambda.reset(new SiconosVector(sDim));
  _lambda = _interactionSMC->lambda(0);
  _us.reset(new SiconosVector(sDim));
  _ueq.reset(new SiconosVector(sDim));

  if (_Csurface)
  {
    SP::SimpleMatrix tmpM(new SimpleMatrix(_Csurface->size(0), _B->size(1)));
    _invCB.reset(new SimpleMatrix(*tmpM));
    prod(*_Csurface, *_B, *tmpM);
    invertMatrix(*tmpM, *_invCB);
  }
}

void CommonSMC::computeUeq()
{
  assert(Type::value(*_DS_SMC) != Type::FirstOrderNonLinearDS && "CommonSMC::computeUeq the DS should be linear");
  assert(_Csurface && "CommonSMC::computeUeq the sliding variable should be linear subpsace of the state");
  FirstOrderLinearDS& LinearDS_SMC = *std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC);
  unsigned int n = LinearDS_SMC.A()->size(1);
  // equivalent part, explicit contribution
  SP::SimpleMatrix tmpM1(new SimpleMatrix(_Csurface->size(0), n));
  SP::SimpleMatrix tmpN(new SimpleMatrix(n, n));
  SP::SimpleMatrix quasiProjB_A(new SimpleMatrix(_invCB->size(0), n));
  SP::SimpleMatrix tmpW(new SimpleMatrix(n, n, 0));
  SP::SiconosVector xTk(new SiconosVector(_sensor->y()));
  tmpW->eye();
  prod(*_Csurface, *LinearDS_SMC.A(), *tmpM1);
  // compute (CB)^{-1}CA
  prod(*_invCB, *tmpM1, *quasiProjB_A);
  prod(_thetaSMC-1, *quasiProjB_A, *xTk, *_ueq);

  // equivalent part, implicit contribution
  // XXX when to call this ?
  ZeroOrderHoldOSI& zoh = *std11::static_pointer_cast<ZeroOrderHoldOSI>(_integratorSMC);
  zoh.updateMatrices(_DS_SMC);

  // tmpN = B^{*}(CB)^{-1}CA
  prod(zoh.Bd(_DS_SMC), *quasiProjB_A, *tmpN, true);
  // W = I + \theta B^{*})CB)^{-1}CA
  scal(_thetaSMC, *tmpN, *tmpW, false);
  // compute e^{Ah}x_k
  prod(zoh.Ad(_DS_SMC), *xTk, *xTk);
  // xTk = (e^{Ah}-(1-\theta)\Psi_k\Pi_B A)x_k
  prod(_thetaSMC-1, *tmpN, _sensor->y(), *xTk, false);
  // compute the solution x_{k+1} of the system W*x_{k+1} = x_k
  tmpW->PLUForwardBackwardInPlace(*xTk);
  // add the contribution from the implicit part to ueq
  prod(-_thetaSMC, *quasiProjB_A, *xTk, *_ueq, false);

}

void CommonSMC::setCsurface(SP::SimpleMatrix newC)
{
  // check dimensions ...
  _Csurface = newC;
}

void CommonSMC::setSaturationMatrix(SP::SimpleMatrix newSat)
{
  // check dimensions ...
  if (newSat->size(1) != _B->size(1))
  {
    RuntimeException::selfThrow("CommonSMC::setSaturationMatrixPtr - inconstency between the dimension of the state space and D");
  }
  else
  {
    _D = newSat;
  }
}

void CommonSMC::setTimeDiscretisation(const TimeDiscretisation& td)
{
  _td.reset(new TimeDiscretisation(td));
}

void CommonSMC::sete(const std::string& plugin)
{
  _plugineName = plugin;
}

void CommonSMC::seth(const std::string& plugin)
{
  _pluginhName = plugin;
}
void CommonSMC::setJachx(const std::string& plugin)
{
  _pluginJachxName = plugin;
}
void CommonSMC::setJachlambda(const std::string& plugin)
{
  _pluginJachlambdaName = plugin;
}
void CommonSMC::setg(const std::string& plugin)
{
  _plugingName = plugin;
}
void CommonSMC::setJacgx(const std::string& plugin)
{
  _pluginJacgxName = plugin;
}
void CommonSMC::setJacglambda(const std::string& plugin)
{
  _pluginJacglambdaName = plugin;
}

<commit_msg>[control] update constructor<commit_after>/* Siconos is a program dedicated to modeling, simulation and control
 * of non smooth dynamical systems.
 *
 * Copyright 2016 INRIA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

#include "ModelingTools.hpp"
#include "SimulationTools.hpp"
#include "CommonSMC.hpp"
#include "ControlSensor.hpp"
#include "FirstOrderR_helpers.hpp"

#include <string>

void CommonSMC::initialize(const NonSmoothDynamicalSystem & nsds, const Simulation & s)
{
  if (!_Csurface && _pluginhName.empty())
  {
    RuntimeException::selfThrow("CommonSMC::initialize - you have to set either _Csurface or h(.) before initializing the Actuator");
  }
  else
  {
    if (_Csurface && !_u)
      _u.reset(new SiconosVector(_Csurface->size(0), 0));

    Actuator::initialize(nsds,s);
  }
  // We can only work with FirstOrderNonLinearDS, FirstOrderLinearDS and FirstOrderLinearTIDS
  // We can use the Visitor mighty power to check if we have the right type
  SP::DynamicalSystem DS = _sensor->getDS();
  Type::Siconos dsType;
  dsType = Type::value(*DS);

  // create the DS for the controller
  // if the DS we use is different from the DS we are controlling
  // when we want for instant to see how well the controller behaves
  // if the plant model is not exact, we can use the setSimulatedDS
  // method
  if (dsType == Type::FirstOrderNonLinearDS)
  {
    _DS_SMC.reset(new FirstOrderNonLinearDS(*(std11::static_pointer_cast<FirstOrderNonLinearDS>(DS))));
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderNonLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else if (dsType == Type::FirstOrderLinearDS)
  {
    _DS_SMC.reset(new FirstOrderLinearDS(*(std11::static_pointer_cast<FirstOrderLinearDS>(DS))));
    std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setComputebFunction(NULL);
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else if (dsType == Type::FirstOrderLinearTIDS)
  {
    _DS_SMC.reset(new FirstOrderLinearTIDS(*(std11::static_pointer_cast<FirstOrderLinearTIDS>(DS))));
  // We have to reset the _pluginb
  SP::SiconosVector dummyb(new SiconosVector(_DS_SMC->n(), 0));
  std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC)->setbPtr(dummyb);
  }
  else
  {
    RuntimeException::selfThrow("LinearSMC is not yet implemented for system of type" + dsType);
  }
  // Get the dimension of the output
  // XXX What if there is more than one sensor ...
  double t0 = nsds.t0();
  double T = nsds.finalT() + _td->currentTimeStep(0);
  // create the SMC Model
  _nsdsSMC.reset(new NonSmoothDynamicalSystem(t0, T));
  // Set up the simulation
  _simulationSMC.reset(new TimeStepping(_nsdsSMC,_td));

  unsigned int sDim = _u->size();
  // create the interaction
  if (!_plugingName.empty())
  {
    if (_pluginhName.empty())
      RuntimeException::selfThrow("LinearSMC::initialize - the Controller has a function g set but _pluginhName is not set\n You must supply a function to compute y=h(x,...)");
    if (!_pluginJacgxName.empty()) // Is the relation the most generic NL one ?
    {
      _relationSMC.reset(new FirstOrderNonLinearR());
      _relationSMC->setComputeJacgxFunction(SSLH::getPluginName(_pluginJacgxName), SSLH::getPluginFunctionName(_pluginJacgxName));

      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
      if (_pluginJachlambdaName.empty() && !_D)
        _D.reset(new SimpleMatrix(sDim, sDim, 0));
      FirstOrderRHelpers::JachlambdaSetter(*_relationSMC, _D, _pluginJachlambdaName);

    }
    else if (!_pluginJachlambdaName.empty() || _D) // Type2R ?
    {
      _relationSMC.reset(new FirstOrderType2R());
      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
      FirstOrderRHelpers::JachlambdaSetter(*_relationSMC, _D, _pluginJachlambdaName);
    }
    else // Type1R
    {
      _relationSMC.reset(new FirstOrderType1R());
      FirstOrderRHelpers::JacglambdaSetter(*_relationSMC, _B, _pluginJacglambdaName);
      FirstOrderRHelpers::JachxSetter(*_relationSMC, _Csurface, _pluginJachxName);
    }

    _relationSMC->setComputehFunction(SSLH::getPluginName(_pluginhName), SSLH::getPluginFunctionName(_pluginhName));
    _relationSMC->setComputegFunction(SSLH::getPluginName(_plugingName), SSLH::getPluginFunctionName(_plugingName));

    if (_computeResidus)
    {
      _simulationSMC->setComputeResiduY(true);
      _simulationSMC->setComputeResiduR(true);
      _simulationSMC->setUseRelativeConvergenceCriteron(false);
    }
  }
  else
  {
    if (!_plugineName.empty())
    {
      _relationSMC.reset(new FirstOrderLinearR(_Csurface, _B));
      _relationSMC->setComputeEFunction(SSLH::getPluginName(_plugineName), SSLH::getPluginFunctionName(_plugineName));
    }
    else
    {
      _relationSMC.reset(new FirstOrderLinearTIR(_Csurface, _B));
    }
      std11::static_pointer_cast<FirstOrderLinearTIR>(_relationSMC)->setDPtr(_D);
  }

  // _nsLawSMC and the OSNSP can be defined in derived classes, like twisting
  if (!_nsLawSMC)  _nsLawSMC.reset(new RelayNSL(sDim, -_alpha, _alpha));
  if (!_OSNSPB_SMC) _OSNSPB_SMC.reset(new Relay(_numericsSolverId));

  _interactionSMC.reset(new Interaction(_nsLawSMC, _relationSMC));

  if (dsType == Type::FirstOrderNonLinearDS)
  {
    _integratorSMC.reset(new EulerMoreauOSI(_thetaSMC));
  }
  else
  {
    _integratorSMC.reset(new ZeroOrderHoldOSI());
  }

  _nsdsSMC->insertDynamicalSystem(_DS_SMC);
  _nsdsSMC->setName(_DS_SMC, "plant_SMC");
  _nsdsSMC->link(_interactionSMC, _DS_SMC);
  _nsdsSMC->setControlProperty(_interactionSMC, true);
  _nsdsSMC->topology()->setName(_interactionSMC, "Sgn_SMC");
  _simulationSMC->setName("linear sliding mode controller simulation");
  _simulationSMC->associate(_integratorSMC, _DS_SMC);
  // OneStepNsProblem
  _OSNSPB_SMC->numericsSolverOptions()->dparam[0] = _precision;
  //    std::cout << _OSNSPB_SMC->numericsSolverOptions()->dparam[0] <<std::endl;
  _simulationSMC->insertNonSmoothProblem(_OSNSPB_SMC);
  // Finally we can initialize everything ...
  _simulationSMC->associate(_integratorSMC,_DS_SMC);

  // _SMC->setSimulation(_simulationSMC);
  // _SMC->initialize();

  // Handy
  _eventsManager = _simulationSMC->eventsManager();
  _lambda.reset(new SiconosVector(sDim));
  _lambda = _interactionSMC->lambda(0);
  _us.reset(new SiconosVector(sDim));
  _ueq.reset(new SiconosVector(sDim));

  if (_Csurface)
  {
    SP::SimpleMatrix tmpM(new SimpleMatrix(_Csurface->size(0), _B->size(1)));
    _invCB.reset(new SimpleMatrix(*tmpM));
    prod(*_Csurface, *_B, *tmpM);
    invertMatrix(*tmpM, *_invCB);
  }
}

void CommonSMC::computeUeq()
{
  assert(Type::value(*_DS_SMC) != Type::FirstOrderNonLinearDS && "CommonSMC::computeUeq the DS should be linear");
  assert(_Csurface && "CommonSMC::computeUeq the sliding variable should be linear subpsace of the state");
  FirstOrderLinearDS& LinearDS_SMC = *std11::static_pointer_cast<FirstOrderLinearDS>(_DS_SMC);
  unsigned int n = LinearDS_SMC.A()->size(1);
  // equivalent part, explicit contribution
  SP::SimpleMatrix tmpM1(new SimpleMatrix(_Csurface->size(0), n));
  SP::SimpleMatrix tmpN(new SimpleMatrix(n, n));
  SP::SimpleMatrix quasiProjB_A(new SimpleMatrix(_invCB->size(0), n));
  SP::SimpleMatrix tmpW(new SimpleMatrix(n, n, 0));
  SP::SiconosVector xTk(new SiconosVector(_sensor->y()));
  tmpW->eye();
  prod(*_Csurface, *LinearDS_SMC.A(), *tmpM1);
  // compute (CB)^{-1}CA
  prod(*_invCB, *tmpM1, *quasiProjB_A);
  prod(_thetaSMC-1, *quasiProjB_A, *xTk, *_ueq);

  // equivalent part, implicit contribution
  // XXX when to call this ?
  ZeroOrderHoldOSI& zoh = *std11::static_pointer_cast<ZeroOrderHoldOSI>(_integratorSMC);
  zoh.updateMatrices(_DS_SMC);

  // tmpN = B^{*}(CB)^{-1}CA
  prod(zoh.Bd(_DS_SMC), *quasiProjB_A, *tmpN, true);
  // W = I + \theta B^{*})CB)^{-1}CA
  scal(_thetaSMC, *tmpN, *tmpW, false);
  // compute e^{Ah}x_k
  prod(zoh.Ad(_DS_SMC), *xTk, *xTk);
  // xTk = (e^{Ah}-(1-\theta)\Psi_k\Pi_B A)x_k
  prod(_thetaSMC-1, *tmpN, _sensor->y(), *xTk, false);
  // compute the solution x_{k+1} of the system W*x_{k+1} = x_k
  tmpW->PLUForwardBackwardInPlace(*xTk);
  // add the contribution from the implicit part to ueq
  prod(-_thetaSMC, *quasiProjB_A, *xTk, *_ueq, false);

}

void CommonSMC::setCsurface(SP::SimpleMatrix newC)
{
  // check dimensions ...
  _Csurface = newC;
}

void CommonSMC::setSaturationMatrix(SP::SimpleMatrix newSat)
{
  // check dimensions ...
  if (newSat->size(1) != _B->size(1))
  {
    RuntimeException::selfThrow("CommonSMC::setSaturationMatrixPtr - inconstency between the dimension of the state space and D");
  }
  else
  {
    _D = newSat;
  }
}

void CommonSMC::setTimeDiscretisation(const TimeDiscretisation& td)
{
  _td.reset(new TimeDiscretisation(td));
}

void CommonSMC::sete(const std::string& plugin)
{
  _plugineName = plugin;
}

void CommonSMC::seth(const std::string& plugin)
{
  _pluginhName = plugin;
}
void CommonSMC::setJachx(const std::string& plugin)
{
  _pluginJachxName = plugin;
}
void CommonSMC::setJachlambda(const std::string& plugin)
{
  _pluginJachlambdaName = plugin;
}
void CommonSMC::setg(const std::string& plugin)
{
  _plugingName = plugin;
}
void CommonSMC::setJacgx(const std::string& plugin)
{
  _pluginJacgxName = plugin;
}
void CommonSMC::setJacglambda(const std::string& plugin)
{
  _pluginJacglambdaName = plugin;
}

<|endoftext|>


<commit_before>#include <assert.h>
#include <math.h>
#include "point.h"

Point::Point(double _x, double _y)
  : x(_x), y(_y)
{
}

Point::Point(const Point& point)
  : x(point.x), y(point.y)
{
}

double Point::distance(const Point& point) const {
    return sqrt(pow((x-point.x), 2) + pow((y-point.y),2));
}

ostream& operator << (ostream& os, const Point& point) {
    os << "(" << point.x << "," << point.y << ")";
    return os;
}

istream& operator >> (istream& is, Point& point) {
    char po, vir, pf;
    is >> po;
    if(is){
        is >> point.x >> vir >> point.y >> pf;
        assert(po=='(');
        assert(vir==',');
        assert(pf==')');
    }
    return is;
}
<commit_msg> version a remettre<commit_after>#include <assert.h>
#include <math.h>
#include "point.h"

Point::Point(double _x, double _y)
  : x(_x), y(_y)
{
}

Point::Point(const Point& point)
  : x(point.x), y(point.y)
{
}

double Point::distance(const Point& point) const {
    return sqrt(pow((x-point.x), 2) + pow((y-point.y),2));
}

ostream& operator << (ostream& os, const Point& point) {
    os << "(" << point.x << "," << point.y << ")";
    return os;
}

istream& operator >> (istream& is, Point& point) {
    char po, vir, pf;
    is >> po;
    if(is){
        is >> point.x >> vir >> point.y >> pf;
        assert(po=='(');
        assert(vir==',');
        assert(pf==')');
    }
    return is;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: gtkgdi.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: kz $ $Date: 2007-12-12 13:21:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef _VCL_GTKGDI_HXX
#define _VCL_GTKGDI_HXX

#include <prex.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <postx.h>

#ifndef _SV_SALGDI_H
#include <salgdi.h>
#endif

class GtkSalGraphics : public X11SalGraphics
{
    GtkWidget           *m_pWindow;
    Region               m_aClipRegion;

public:
                        GtkSalGraphics( GtkWidget *window )
                            : m_pWindow( window ),
                              m_aClipRegion( REGION_NULL )
                              {}
    virtual             ~GtkSalGraphics();

    inline GtkWidget*  GetGtkWidget() const { return m_pWindow; }
    inline GdkWindow*  GetGdkWindow() const { return m_pWindow->window; }
    inline GtkSalFrame* GetGtkFrame() const { return static_cast<GtkSalFrame*>(m_pFrame); }
    void SetWindow( GtkWidget* window ) { m_pWindow = window; }

    // will be set when UI theme was changed
    static  BOOL        bThemeChanged;
    static  BOOL        bNeedPixmapPaint;
    static  BOOL        bGlobalNeedPixmapPaint;
    static  BOOL        bToolbarGripWorkaround;
    static  BOOL        bNeedButtonStyleAsEditBackgroundWorkaround;

    // native widget methods
    virtual BOOL        IsNativeControlSupported( ControlType nType, ControlPart nPart );
    virtual BOOL        hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                              const Point& aPos, SalControlHandle& rControlHandle, BOOL& rIsInside );
    virtual BOOL        drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                           ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle,
                                           const rtl::OUString& rCaption );
    virtual BOOL        drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                               ControlState nState, const ImplControlValue& aValue,
                                               SalControlHandle& rControlHandle, const rtl::OUString& rCaption );
    virtual BOOL        getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState,
                                                const ImplControlValue& aValue, SalControlHandle& rControlHandle, const rtl::OUString& rCaption,
                                                Region &rNativeBoundingRegion, Region &rNativeContentRegion );

    //helper methods for frame's UpdateSettings
    void updateSettings( AllSettings& rSettings );

    virtual void            ResetClipRegion();
    virtual void            BeginSetClipRegion( ULONG nCount );
    virtual BOOL            unionClipRegion( long nX, long nY, long nWidth, long nHeight );
    virtual void            EndSetClipRegion();

    // some themes set the background pixmap of our window EVERY time
    // a control is painted; but presentation effects need
    // the background set to None; workaround: set the background
    // before copyBits
    virtual void            copyBits( const SalTwoRect* pPosAry,
                                      SalGraphics* pSrcGraphics );

protected:
    typedef std::list< Rectangle > clipList;

    GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect );
    BOOL NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect );

    BOOL NWPaintGTKButton( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                           const Rectangle& rControlRectangle,
                           const clipList& rClipList,
                           ControlState nState, const ImplControlValue& aValue,
                           SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKRadio( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                          const Rectangle& rControlRectangle,
                          const clipList& rClipList,
                          ControlState nState, const ImplControlValue& aValue,
                          SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKCheck( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                          const Rectangle& rControlRectangle,
                          const clipList& rClipList,
                          ControlState nState, const ImplControlValue& aValue,
                          SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKScrollbar( ControlType nType, ControlPart nPart,
                              const Rectangle& rControlRectangle,
                              const clipList& rClipList,
                              ControlState nState, const ImplControlValue& aValue,
                              SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKEditBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKComboBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                             const Rectangle& rControlRectangle,
                             const clipList& rClipList,
                             ControlState nState, const ImplControlValue& aValue,
                             SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKTabItem( ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKListBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );

    BOOL NWPaintGTKToolbar( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKMenubar( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKPopupMenu( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                              const Rectangle& rControlRectangle,
                              const clipList& rClipList,
                              ControlState nState, const ImplControlValue& aValue,
                              SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKTooltip( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );

    BOOL drawNativeMixedStateCheck( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                    ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle,
                                    const rtl::OUString& rCaption );
};

#endif // _VCL_GTKGDI_HXX
<commit_msg>INTEGRATION: CWS vcl86_DEV300 (1.12.22); FILE MERGED 2008/01/07 14:44:48 pl 1.12.22.1: #i85052# native progress<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: gtkgdi.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 16:50:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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
 *
 ************************************************************************/

#ifndef _VCL_GTKGDI_HXX
#define _VCL_GTKGDI_HXX

#include <prex.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <postx.h>

#ifndef _SV_SALGDI_H
#include <salgdi.h>
#endif

class GtkSalGraphics : public X11SalGraphics
{
    GtkWidget           *m_pWindow;
    Region               m_aClipRegion;

public:
                        GtkSalGraphics( GtkWidget *window )
                            : m_pWindow( window ),
                              m_aClipRegion( REGION_NULL )
                              {}
    virtual             ~GtkSalGraphics();

    inline GtkWidget*  GetGtkWidget() const { return m_pWindow; }
    inline GdkWindow*  GetGdkWindow() const { return m_pWindow->window; }
    inline GtkSalFrame* GetGtkFrame() const { return static_cast<GtkSalFrame*>(m_pFrame); }
    void SetWindow( GtkWidget* window ) { m_pWindow = window; }

    // will be set when UI theme was changed
    static  BOOL        bThemeChanged;
    static  BOOL        bNeedPixmapPaint;
    static  BOOL        bGlobalNeedPixmapPaint;
    static  BOOL        bToolbarGripWorkaround;
    static  BOOL        bNeedButtonStyleAsEditBackgroundWorkaround;

    // native widget methods
    virtual BOOL        IsNativeControlSupported( ControlType nType, ControlPart nPart );
    virtual BOOL        hitTestNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                              const Point& aPos, SalControlHandle& rControlHandle, BOOL& rIsInside );
    virtual BOOL        drawNativeControl( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                           ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle,
                                           const rtl::OUString& rCaption );
    virtual BOOL        drawNativeControlText( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                               ControlState nState, const ImplControlValue& aValue,
                                               SalControlHandle& rControlHandle, const rtl::OUString& rCaption );
    virtual BOOL        getNativeControlRegion( ControlType nType, ControlPart nPart, const Region& rControlRegion, ControlState nState,
                                                const ImplControlValue& aValue, SalControlHandle& rControlHandle, const rtl::OUString& rCaption,
                                                Region &rNativeBoundingRegion, Region &rNativeContentRegion );

    //helper methods for frame's UpdateSettings
    void updateSettings( AllSettings& rSettings );

    virtual void            ResetClipRegion();
    virtual void            BeginSetClipRegion( ULONG nCount );
    virtual BOOL            unionClipRegion( long nX, long nY, long nWidth, long nHeight );
    virtual void            EndSetClipRegion();

    // some themes set the background pixmap of our window EVERY time
    // a control is painted; but presentation effects need
    // the background set to None; workaround: set the background
    // before copyBits
    virtual void            copyBits( const SalTwoRect* pPosAry,
                                      SalGraphics* pSrcGraphics );

protected:
    typedef std::list< Rectangle > clipList;

    GdkPixmap* NWGetPixmapFromScreen( Rectangle srcRect );
    BOOL NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect );

    BOOL NWPaintGTKButton( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                           const Rectangle& rControlRectangle,
                           const clipList& rClipList,
                           ControlState nState, const ImplControlValue& aValue,
                           SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKRadio( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                          const Rectangle& rControlRectangle,
                          const clipList& rClipList,
                          ControlState nState, const ImplControlValue& aValue,
                          SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKCheck( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                          const Rectangle& rControlRectangle,
                          const clipList& rClipList,
                          ControlState nState, const ImplControlValue& aValue,
                          SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKScrollbar( ControlType nType, ControlPart nPart,
                              const Rectangle& rControlRectangle,
                              const clipList& rClipList,
                              ControlState nState, const ImplControlValue& aValue,
                              SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKEditBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKComboBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                             const Rectangle& rControlRectangle,
                             const clipList& rClipList,
                             ControlState nState, const ImplControlValue& aValue,
                             SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKTabItem( ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKListBox( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );

    BOOL NWPaintGTKToolbar( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKMenubar( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKPopupMenu( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                              const Rectangle& rControlRectangle,
                              const clipList& rClipList,
                              ControlState nState, const ImplControlValue& aValue,
                              SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKTooltip( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );
    BOOL NWPaintGTKProgress( GdkDrawable* gdkDrawable, ControlType nType, ControlPart nPart,
                            const Rectangle& rControlRectangle,
                            const clipList& rClipList,
                            ControlState nState, const ImplControlValue& aValue,
                            SalControlHandle& rControlHandle, const OUString& rCaption );

    BOOL drawNativeMixedStateCheck( ControlType nType, ControlPart nPart, const Region& rControlRegion,
                                    ControlState nState, const ImplControlValue& aValue, SalControlHandle& rControlHandle,
                                    const rtl::OUString& rCaption );
};

#endif // _VCL_GTKGDI_HXX
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <typeinfo>
#include <ctype.h>

#define CUR_TOKEN tokens[cur_pos]

enum TokenType{
  TOKEN_BRACKET_OPEN,
  TOKEN_BRACKET_CLOSE,
  TOKEN_SYMBOL,
  TOKEN_STRING,
  TOKEN_NIL,
};

class Token {
public:
  TokenType type;
  std::string value;

  Token(TokenType atype) : type(atype), value(std::string()) {
  }

  Token(TokenType atype, std::string avalue) : type(atype), value(avalue) {
  }
};

namespace Lisp {
  class Expression {
  public:
    virtual ~Expression() {}

    virtual std::string lisp_str() = 0;
  };

  class CallFunction : public Expression {
  public:
    std::string name;
    std::vector<Expression*> args;

    CallFunction(std::string aname, std::vector<Expression*> &aargs) : name(aname), args(aargs) {}
    ~CallFunction() {
      for(size_t i = 0 ; i < args.size() ; i++) {
        delete args[i];
      }
    }

    std::string lisp_str() {
      std::stringstream ss;
      ss << "(" << name << " ";
      for(Expression* arg : args) {
        ss << arg->lisp_str() << " ";
      }
      ss << ")";
      return ss.str();
    }
  };

  class String : public Expression {
  public:
    std::string value;

    String(std::string &avalue) : value(avalue) {}

    std::string lisp_str() { return '"' + value + '"'; }
  };

  class List : public Expression {
  public:
    std::vector<Expression*> values;

    List(std::vector<Expression*> &avalues) : values(avalues) {}

    std::string lisp_str() {
      std::stringstream ss;
      ss << "(";
      for(Expression* value : values) {
        ss << value->lisp_str() << " ";
      }
      ss << ")";
      return ss.str();
    }
  };

  // TODO: RubyみたくExpression*に埋め込みたい
  class Nil : public Expression {
  public:
    Nil() {}

    std::string lisp_str() { return "nil"; }
  };
}

std::vector<Token*> tokens;
size_t cur_pos;

Lisp::Expression* parse();

Lisp::Expression* parse_call_fun() {
  cur_pos++;
  if(CUR_TOKEN->type != TOKEN_SYMBOL) {
    //TODO: raise an error
  }
  std::string name;
  name = CUR_TOKEN->value;

  cur_pos++;
  std::vector<Lisp::Expression*> args;
  for(; cur_pos < tokens.size() && CUR_TOKEN->type != TOKEN_BRACKET_CLOSE ; cur_pos++) {
    args.push_back(parse());
  }

  cur_pos++;

  return new Lisp::CallFunction(name, args);
}

Lisp::Expression* parse() {
  switch(CUR_TOKEN->type) {
    case TOKEN_BRACKET_OPEN:
      return parse_call_fun();
    case TOKEN_STRING:
      return new Lisp::String(CUR_TOKEN->value);
    case TOKEN_NIL:
      return new Lisp::Nil();
    default:
      //TODO: raise an error
      return nullptr;
  }
}

bool is_symbol(char c) {
  return isalnum(c) && isalpha(c);
}

int main() {
  using namespace std;

  string code;
  //code.reserve(1024);
  vector<Lisp::Expression*> exprs;

  char ch;
  while((ch = cin.get()) != std::char_traits<char>::eof()) {
    code.push_back(ch);
  }

  for(size_t i = 0 ; i < code.size() - 1 ; i++) { //TODO: -1を修正(EOFっぽい?)
    char ch = code[i];
    if(ch == '(')
      tokens.push_back(new Token(TOKEN_BRACKET_OPEN));
    else if(ch == ')')
      tokens.push_back(new Token(TOKEN_BRACKET_CLOSE));
    else if(ch == '"') { // string
      i++;

      size_t token_len = 0;
      while(code[i + token_len] != '"') {
        token_len++;
        if(i + token_len >= code.size()) {
          //TODO: raise an error
        }
      }
      tokens.push_back(new Token(TOKEN_STRING, code.substr(i, token_len)));
      i += token_len;
    }
    else if(ch == ' ' || ch == '\n')
      ;//skip
    else { // symbol
      size_t token_len = 0;
      while(is_symbol(code[i + token_len])) {
        token_len++;
        if(i + token_len >= code.size()) {
          //TODO: raise an error
        }
      }

      string token_val = code.substr(i, token_len);
      TokenType token_type;
      if(token_val == "nil")
        token_type = TOKEN_NIL;
      else
        token_type = TOKEN_SYMBOL;

      if(token_type == TOKEN_SYMBOL)
        tokens.push_back(new Token(TOKEN_SYMBOL, token_val));
      else
        tokens.push_back(new Token(token_type));

      i += token_len - 1;
    }
  }

  for(auto token : tokens) {
    cout << "token type: " << token->type << ", value: " << token->value << endl;
  }

  // parse
  cur_pos = 0;
  while(cur_pos < tokens.size()) {
    exprs.push_back(parse());
  }

  // evaluate
  for(size_t i = 0 ; i < exprs.size() ; i++) {
    auto expr = exprs[i];

    const type_info& id = typeid(*expr);
    if(id == typeid(Lisp::CallFunction)) {
      auto call_fun = (Lisp::CallFunction*)expr;
      auto name = call_fun->name;
      if(name == "print") {
        for(auto arg : call_fun->args) {
          cout << ((Lisp::String*)arg)->value;
        }
        exprs[i] = new Lisp::Nil;
      }
      else if(name == "inspect") {
        cout << call_fun->args[0]->lisp_str() << endl;
        exprs[i] = new Lisp::Nil;
      }
      else if(name == "list") {
        exprs[i] = new Lisp::List(call_fun->args);
      }
    }
  }

  // destruction
  for(size_t i = 0 ; i < tokens.size() ; i++) {
    delete tokens[i];
  }

  for(size_t i = 0 ; i < exprs.size() ; i++) {
    delete exprs[i];
  }

  return 0;
}
<commit_msg>構文解析器をクラス化した<commit_after>#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <list>
#include <typeinfo>
#include <ctype.h>

#define PRINT_LINE (std::cout << "line: " << __LINE__ << std::endl)

enum TokenType{
  TOKEN_BRACKET_OPEN,
  TOKEN_BRACKET_CLOSE,
  TOKEN_SYMBOL,
  TOKEN_STRING,
  TOKEN_NIL,
};

class Token {
public:
  TokenType type;
  std::string value;

  Token(TokenType atype) : type(atype), value(std::string()) {
  }

  Token(TokenType atype, std::string avalue) : type(atype), value(avalue) {
  }

  std::string str() {
    std::stringstream ss;
    ss << "Token(" << type << ", " << value << ")";
    return ss.str();
  }
};

namespace Lisp {
  class Expression {
  public:
    virtual ~Expression() {}

    virtual std::string lisp_str() = 0;
  };

  class CallFunction : public Expression {
  public:
    std::string name;
    std::vector<Expression*> args;

    CallFunction(std::string aname, std::vector<Expression*> &aargs) : name(aname), args(aargs) {}
    ~CallFunction() {
      for(size_t i = 0 ; i < args.size() ; i++) {
        delete args[i];
      }
    }

    std::string lisp_str() {
      std::stringstream ss;
      ss << "(" << name << " ";
      for(Expression* arg : args) {
        ss << arg->lisp_str() << " ";
      }
      ss << ")";
      return ss.str();
    }
  };

  class String : public Expression {
  public:
    std::string value;

    String(std::string &avalue) : value(avalue) {}

    std::string lisp_str() { return '"' + value + '"'; }
  };

  class List : public Expression {
  public:
    std::vector<Expression*> values;

    List(std::vector<Expression*> &avalues) : values(avalues) {}

    std::string lisp_str() {
      std::stringstream ss;
      ss << "(";
      for(Expression* value : values) {
        ss << value->lisp_str() << " ";
      }
      ss << ")";
      return ss.str();
    }
  };

  // TODO: RubyみたくExpression*に埋め込みたい
  class Nil : public Expression {
  public:
    Nil() {}

    std::string lisp_str() { return "nil"; }
  };

  class Parser {
  public:
    std::vector<Expression*> parse(const std::string &code) {
      tokens = tokenize(code);

      /*for(auto tok : tokens) {
        std::cout << tok->str() << std::endl;
      }*/

      std::vector<Expression*> exprs;
      while(!tokens.empty()) {
        exprs.push_back(parse_expr());
      }
      return exprs;
    }

  private:
    std::list<Token*> tokens;

    inline Token* cur_token() {
      return tokens.empty() ? nullptr : tokens.front();
    }

    void consume_token() {
      auto ctoken = cur_token();
      if(ctoken) delete ctoken;

      if(!tokens.empty()) tokens.pop_front();
    }

    Expression* parse_call_fun() {
      consume_token();
      if(cur_token()->type != TOKEN_SYMBOL) {
        //TODO: raise an error
      }
      std::string name;
      name = cur_token()->value;

      consume_token();
      std::vector<Expression*> args;
      for(; !tokens.empty() && cur_token()->type != TOKEN_BRACKET_CLOSE ; consume_token()) {
        args.push_back(parse_expr());
      }

      consume_token();

      return new CallFunction(name, args);
    }

    Expression* parse_expr() {
      switch(cur_token()->type) {
        case TOKEN_BRACKET_OPEN:
          return parse_call_fun();
        case TOKEN_STRING:
          return new String(cur_token()->value);
        case TOKEN_NIL:
          return new Nil();
        default:
          //TODO: raise an error
          return nullptr;
      }
    }

    bool is_symbol(char c) {
      return isalnum(c) && isalpha(c);
    }

    std::list<Token*> tokenize(const std::string &code) {
      std::list<Token*> tokens;

      for(size_t i = 0 ; i < code.size() - 1 ; i++) { //TODO: -1を修正(EOFっぽい?)
        char ch = code[i];
        if(ch == '(')
          tokens.push_back(new Token(TOKEN_BRACKET_OPEN));
        else if(ch == ')')
          tokens.push_back(new Token(TOKEN_BRACKET_CLOSE));
        else if(ch == '"') { // string
          i++;

          size_t token_len = 0;
          while(code[i + token_len] != '"') {
            token_len++;
            if(i + token_len >= code.size()) {
              //TODO: raise an error
            }
          }
          tokens.push_back(new Token(TOKEN_STRING, code.substr(i, token_len)));
          i += token_len;
        }
        else if(ch == ' ' || ch == '\n')
          ;//skip
        else { // symbol
          size_t token_len = 0;
          while(is_symbol(code[i + token_len])) {
            token_len++;
            if(i + token_len >= code.size()) {
              //TODO: raise an error
            }
          }

          std::string token_val = code.substr(i, token_len);
          TokenType token_type;
          if(token_val == "nil")
            token_type = TOKEN_NIL;
          else
            token_type = TOKEN_SYMBOL;

          if(token_type == TOKEN_SYMBOL)
            tokens.push_back(new Token(TOKEN_SYMBOL, token_val));
          else
            tokens.push_back(new Token(token_type));

          i += token_len - 1;
        }
      }

      return tokens;
    }
  };
}

int main() {
  using namespace std;

  string code;
  //code.reserve(1024);

  char ch;
  while((ch = cin.get()) != std::char_traits<char>::eof()) {
    code.push_back(ch);
  }

  Lisp::Parser parser;
  auto exprs = parser.parse(code);

  // evaluate
  for(size_t i = 0 ; i < exprs.size() ; i++) {
    auto expr = exprs[i];

    const type_info& id = typeid(*expr);
    if(id == typeid(Lisp::CallFunction)) {
      auto call_fun = (Lisp::CallFunction*)expr;
      auto name = call_fun->name;
      if(name == "print") {
        for(auto arg : call_fun->args) {
          cout << ((Lisp::String*)arg)->value;
        }
        exprs[i] = new Lisp::Nil;
      }
      else if(name == "inspect") {
        cout << call_fun->args[0]->lisp_str() << endl;
        exprs[i] = new Lisp::Nil;
      }
      else if(name == "list") {
        exprs[i] = new Lisp::List(call_fun->args);
      }
    }
  }

  // destruction
  for(size_t i = 0 ; i < exprs.size() ; i++) {
    delete exprs[i];
  }

  return 0;
}
<|endoftext|>


<commit_before>//===-- examples/HowToUseJIT/HowToUseJIT.cpp - An example use of the JIT --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This small program provides an example of how to quickly build a small
//  module with two functions and execute it with the JIT.
//
// Goal:
//  The goal of this snippet is to create in the memory
//  the LLVM module consisting of two functions as follow:
//
// int add1(int x) {
//   return x+1;
// }
//
// int foo() {
//   return add1(10);
// }
//
// then compile the module via JIT, then execute the `foo'
// function and return result to a driver, i.e. to a "host program".
//
// Some remarks and questions:
//
// - could we invoke some code using noname functions too?
//   e.g. evaluate "foo()+foo()" without fears to introduce
//   conflict of temporary function name with some real
//   existing function name?
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

int main() {

  InitializeNativeTarget();

  LLVMContext Context;

  // Create some module to put our function into it.
  Module *M = new Module("test", Context);

  // Create the add1 function entry and insert this entry into module M.  The
  // function will have a return type of "int" and take an argument of "int".
  // The '0' terminates the list of argument types.
  Function *Add1F =
    cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
                                          Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the function. As before, it automatically inserts
  // because of the last argument.
  BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);

  // Get pointers to the constant `1'.
  Value *One = ConstantInt::get(Type::getInt32Ty(Context), 1);

  // Get pointers to the integer argument of the add1 function...
  assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
  Argument *ArgX = Add1F->arg_begin();  // Get the arg
  ArgX->setName("AnArg");            // Give it a nice symbolic name for fun.

  // Create the add instruction, inserting it into the end of BB.
  Instruction *Add = BinaryOperator::CreateAdd(One, ArgX, "addresult", BB);

  // Create the return instruction and add it to the basic block
  ReturnInst::Create(Context, Add, BB);

  // Now, function add1 is ready.

  // Now we going to create function `foo', which returns an int and takes no
  // arguments.
  Function *FooF =
    cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the FooF function.
  BB = BasicBlock::Create(Context, "EntryBlock", FooF);

  // Get pointers to the constant `10'.
  Value *Ten = ConstantInt::get(Type::getInt32Ty(Context), 10);

  // Pass Ten to the call call:
  CallInst *Add1CallRes = CallInst::Create(Add1F, Ten, "add1", BB);
  Add1CallRes->setTailCall(true);

  // Create the return instruction and add it to the basic block.
  ReturnInst::Create(Context, Add1CallRes, BB);

  // Now we create the JIT.
  ExecutionEngine* EE = EngineBuilder(M).create();

  outs() << "We just constructed this LLVM module:\n\n" << *M;
  outs() << "\n\nRunning foo: ";
  outs().flush();

  // Call the `foo' function with no arguments:
  std::vector<GenericValue> noargs;
  GenericValue gv = EE->runFunction(FooF, noargs);

  // Import result of execution:
  outs() << "Result: " << gv.IntVal << "\n";
  EE->freeMachineCodeForFunction(FooF);
  delete EE;
  llvm_shutdown();
  return 0;
}
<commit_msg>Have the JIT tutorial use IRBuilder for the IR.<commit_after>//===-- examples/HowToUseJIT/HowToUseJIT.cpp - An example use of the JIT --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This small program provides an example of how to quickly build a small
//  module with two functions and execute it with the JIT.
//
// Goal:
//  The goal of this snippet is to create in the memory
//  the LLVM module consisting of two functions as follow:
//
// int add1(int x) {
//   return x+1;
// }
//
// int foo() {
//   return add1(10);
// }
//
// then compile the module via JIT, then execute the `foo'
// function and return result to a driver, i.e. to a "host program".
//
// Some remarks and questions:
//
// - could we invoke some code using noname functions too?
//   e.g. evaluate "foo()+foo()" without fears to introduce
//   conflict of temporary function name with some real
//   existing function name?
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/IRBuilder.h"

using namespace llvm;

int main() {

  InitializeNativeTarget();

  LLVMContext Context;

  // Create some module to put our function into it.
  Module *M = new Module("test", Context);

  // Create the add1 function entry and insert this entry into module M.  The
  // function will have a return type of "int" and take an argument of "int".
  // The '0' terminates the list of argument types.
  Function *Add1F =
    cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
                                          Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the function. As before, it automatically inserts
  // because of the last argument.
  BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);

  // Create a basic block builder with default parameters.  The builder will
  // automatically append instructions to the basic block `BB'.
  IRBuilder<> builder(BB);

  // Get pointers to the constant `1'.
  Value *One = builder.getInt32(1);

  // Get pointers to the integer argument of the add1 function...
  assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
  Argument *ArgX = Add1F->arg_begin();  // Get the arg
  ArgX->setName("AnArg");            // Give it a nice symbolic name for fun.

  // Create the add instruction, inserting it into the end of BB.
  Value *Add = builder.CreateAdd(One, ArgX);

  // Create the return instruction and add it to the basic block
  builder.CreateRet(Add);

  // Now, function add1 is ready.

  // Now we going to create function `foo', which returns an int and takes no
  // arguments.
  Function *FooF =
    cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the FooF function.
  BB = BasicBlock::Create(Context, "EntryBlock", FooF);

  // Tell the basic block builder to attach itself to the new basic block
  builder.SetInsertPoint(BB);

  // Get pointer to the constant `10'.
  Value *Ten = builder.getInt32(10);

  // Pass Ten to the call to Add1F
  CallInst *Add1CallRes = builder.CreateCall(Add1F, Ten);
  Add1CallRes->setTailCall(true);

  // Create the return instruction and add it to the basic block.
  builder.CreateRet(Add1CallRes);

  // Now we create the JIT.
  ExecutionEngine* EE = EngineBuilder(M).create();

  outs() << "We just constructed this LLVM module:\n\n" << *M;
  outs() << "\n\nRunning foo: ";
  outs().flush();

  // Call the `foo' function with no arguments:
  std::vector<GenericValue> noargs;
  GenericValue gv = EE->runFunction(FooF, noargs);

  // Import result of execution:
  outs() << "Result: " << gv.IntVal << "\n";
  EE->freeMachineCodeForFunction(FooF);
  delete EE;
  llvm_shutdown();
  return 0;
}
<|endoftext|>


<commit_before>/**
 * Tact Library for handling capacitive sensing.
 * Copyright (C) 2013, Tomek Ness, Jack Rusher and Studio NAND
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Arduino library https://github.com/StudioNAND/tact-arduino-sketch
 * Processing library https://github.com/StudioNAND/tact-processing
 *
 * This example is inspired by Mads Hobye's instructables tutorial
 * http://www.instructables.com/id/Touche-for-Arduino-Advanced-touch-sensing/
 */

// Include Arduino and Tact.h Header
#include "Arduino.h"
#include "Tact.h"

// Constructor
// also sets _useMultiplexer and _runCMD
Tact::Tact(bool useMultiplexer) {

	// initiate all fields in sensorList array to NULL
	for (int i = 0; i < MAX_SENSOR_COUNT; ++i) {
		_sensorList[i] = NULL;
	}

	// set flag: use multiplexed sensor or not?
	_useMultiplexer = useMultiplexer;
}

// Init new Tact Toolkit
void Tact::begin() {

	// Set up frequency generator
	TCCR1A = 0b10000010;
	TCCR1B = 0b00011001;

	// Signal generator pins
	pinMode (7, INPUT);
	pinMode (8, OUTPUT);
	// Sync (test) pin
	pinMode (9, OUTPUT);

	// Multiplexer pins
	if(_useMultiplexer) {
		pinMode (MP_4051_S0, OUTPUT);  // s0
		pinMode (MP_4051_S1, OUTPUT);  // s1
		pinMode (MP_4051_S2, OUTPUT);  // s2
	}
}

// Start Tact with Serial
void Tact::beginSerial(long br) {
	// Start up serial communication
  	Serial.begin(br);

  // flag needed for serial communication
	_runCMD = false;

	// run regular startup
	begin();
}

// Serial Event Delegation
void Tact::readSerial() {

	// While there is anything in the
	// pipe that has not been processed..
	while (Serial.available() > 0) {

		// Read incoming serial data
		byte inByte = Serial.read();

		Serial.println(inByte, DEC);

		switch (inByte) {
			case '\n':
				_runCMD = true;
				break;
			case CMD_SEPARATOR:
				// If token is command-separator: then increment
				// command-index to address the next field of
				// the command-buffer
				_serialCmdIndex++;
				break;
			// If none of the above
			default:
				// Test if byte represents a digit and
				// update existing int value
				if (inByte > 47 && inByte < 58) {
					_serialCmdBuffer[_serialCmdIndex] = _serialCmdBuffer[_serialCmdIndex] * 10 + (int) (inByte - 48);
					// If in range from A-Z
				} else if ( inByte > 64 && inByte < 123 ) {
	        // check if inByte in lowercase range (97-122)
	        if( inByte > 96) {
	          // transform to uppercase
	          inByte -= 32;
	        }

					// Set command key/name.
					_serialCmdKey = inByte;
					// reset the command-index to -1
					_serialCmdIndex = -1;
					// clear list of command parameters
					_serialCmdBuffer[0] = 0;
					_serialCmdBuffer[1] = 0;
					_serialCmdBuffer[2] = 0;
					_serialCmdBuffer[3] = 0;

					// stop cmd if there's more to come
					_runCMD = false;

				} else {
					// ERROR - unexpected token in parameter stream
				}
				break;
		}
	}

	// execute completed Serial command
	if( _runCMD ) {

		// Declare sensor value buffer
    int results[_serialCmdBuffer[CMD_BUFFER_COUNT]];
    // Declare peak and bias vars
    int peak = 0;
    int bias = 0;

		// command is not initial handshake
		if(_serialCmdKey  != 'V') {

			// using multiplex sensor?
			if(_useMultiplexer) {
				// Select the sensor-input / bit
	  		// (use this with arduino 0013+)
	    	digitalWrite (MP_4051_S0, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 0));
	    	digitalWrite (MP_4051_S1, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 1));
	    	digitalWrite (MP_4051_S2, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 2));
	    }

	    for (unsigned int d = 0; d < _serialCmdBuffer[CMD_BUFFER_COUNT]; d++) {
	      // Reload new frequency
	      TCNT1 = 0;
	      ICR1 = _serialCmdBuffer[CMD_BUFFER_START] + _serialCmdBuffer[CMD_BUFFER_STEP] * d;
	      OCR1A = ICR1 / 2;

	      // Restart generator
	      SET (TCCR1B, 0);
	      // Read response signal
	      results[d] = (float) analogRead(0);
	      // Stop generator
	      CLR (TCCR1B, 0);

	      // Check if current result is higher than previously stored peak
	      // if true, overwrite peak and bias
	      if( results[d] > peak ) {
	        peak = results[d];
	        bias = d;
	      }
	    }

			// Announce which of the Tact-inputs that
    	// are multiplexed will be transmitted
    	_sendInt (1024 + _serialCmdBuffer[CMD_BUFFER_PIN]);
		}

		// act depending on command key
		switch (_serialCmdKey) {

			// transmit spectrum
			case 'S':
				// send data_type for data to be transmitted
        _sendInt( 1088 + 0 );
        // Tell client how many data values are going to be sent
       	_sendInt (1098 + _serialCmdBuffer[CMD_BUFFER_COUNT]);
        // Go! Send signal spectrum ...
        for (int x=0; x < _serialCmdBuffer[CMD_BUFFER_COUNT]; x++) {
        	_sendInt(results[x]);
       	}

				break;

			// transmit peak
			case 'P':
				// send data_type for data to be transmitted
	      _sendInt(1088 + 1);
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 1);
	      // send data
				_sendInt(peak);
				break;

			case 'B':
				// send data_type for data to be transmitted
	      _sendInt(1088 + 2);
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 1);
	      // send data
				_sendInt(bias);
				break;

			case 'X':
				// send data_type for data to be transmitted
	      _sendInt( 1088 + 3 );
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 2);
	      // send bias
	      _sendInt(bias);
	      _sendInt(peak);
				break;

			case 'V':
				_sendInt (2124 + VERSION);
				break;

			default:
				; // do nothing
		}

		// command is not initial handshake
		if(_serialCmdKey  != 'V') {
			// Confirm that all data
		  // has been delivered, done!
		  _sendInt (2123);
		}

		_runCMD = false;
	}
}

// Helper to send integers via Serial
/* y = 01010100 11010100    (value is a 2 Byte integer)
 *     yMSB     yLSB        send seperately -> joined by client
 */
void Tact::_sendInt (unsigned int value) {
	Serial.write (byte(lowByte(value)));   // send Low Byte
	Serial.write (byte(highByte(value)));  // send high Byte
	// debug: print ints
	// Serial.println(value);
}

// Add single sensor with ID = 0
void Tact::addSensor(unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// add new sensor to sensor list
	_sensorList[0] = new TactSensor(0, _indexStart, _indexCount, _indexStep);
}

// Add Sensor with custom ID
void Tact::addSensor(unsigned int _sensorID, unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// add new sensor to sensor list
	_sensorList[_sensorID] = new TactSensor(_sensorID, _indexStart, _indexCount, _indexStep);
}

// read data from sensor and refresh data array of object TactSensor
void Tact::_refresh( TactSensor * sensor ) {

	// using multiplex sensor?
	if(_useMultiplexer) {
		// Select the sensor-input / bit
		// (use this with arduino 0013+)
		digitalWrite (MP_4051_S0, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 0));
		digitalWrite (MP_4051_S1, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 1));
		digitalWrite (MP_4051_S2, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 2));
	}

	// reset peak and bias to zero
	sensor->peak = 0;
	// sensor.bias = 0;

  for (unsigned int d = 0; d < sensor->cmdBuffer[CMD_BUFFER_COUNT]; d++) {
	// Reload new frequency
	TCNT1 = 0;
	ICR1 = sensor->cmdBuffer[CMD_BUFFER_START] + sensor->cmdBuffer[CMD_BUFFER_STEP] * d;
	OCR1A = ICR1 / 2;

	// Restart generator
	SET (TCCR1B, 0);

	// Read response signal and write to sensor data container
	sensor->data[d] = (float) analogRead(0);

	// Stop generator
	CLR (TCCR1B, 0);

	// Check if current result is higher than previously stored peak
	// if true, overwrite peak and bias
  	if( sensor->data[d] > sensor->peak ) {
  		// Serial.println(5);
		sensor->peak = sensor->data[d];
      	sensor->bias = d;
  	}

  }

  // Toggle pin 9 after each
	// sweep (good for scope)
	TOG (PORTB, 0);
}

int Tact::readPeak(unsigned int _sensorID) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// return refreshed bias
	return (*_sensorList[_sensorID]).peak;
}

// Tact:Read Bias
int Tact::readBias(unsigned int _sensorID) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// return refreshed bias
	return (*_sensorList[_sensorID]).bias;
}

// read Spectrum and write values to provided array
void Tact::readSpectrum(unsigned int _sensorID, int *targetArray) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// copy required amounts of integers from sensor data array to target array
	memcpy(targetArray, _sensorList[_sensorID]->data, _sensorList[_sensorID]->cmdBuffer[CMD_BUFFER_COUNT] * sizeof(int) );
}

// read Spectrum for single sensor and write values to provided array
void Tact::readSpectrum(int *targetArray) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[0] );
	// work directly with retArray or memcpy into it from elsewhere like
  memcpy(targetArray, _sensorList[0]->data, _sensorList[0]->cmdBuffer[CMD_BUFFER_COUNT] * sizeof(int) );
}

// Constructor for TactSensor
Tact::TactSensor::TactSensor(unsigned int _id, unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// fill config array
	cmdBuffer[CMD_BUFFER_PIN] = _id;
	cmdBuffer[CMD_BUFFER_START] = _indexStart;
	cmdBuffer[CMD_BUFFER_COUNT] = _indexCount;
	cmdBuffer[CMD_BUFFER_STEP] = _indexStep;

	// fill variables
	peak = 0;
	bias = 0;
}

<commit_msg>remove debug comment<commit_after>/**
 * Tact Library for handling capacitive sensing.
 * Copyright (C) 2013, Tomek Ness, Jack Rusher and Studio NAND
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Arduino library https://github.com/StudioNAND/tact-arduino-sketch
 * Processing library https://github.com/StudioNAND/tact-processing
 *
 * This example is inspired by Mads Hobye's instructables tutorial
 * http://www.instructables.com/id/Touche-for-Arduino-Advanced-touch-sensing/
 */

// Include Arduino and Tact.h Header
#include "Arduino.h"
#include "Tact.h"

// Constructor
// also sets _useMultiplexer and _runCMD
Tact::Tact(bool useMultiplexer) {

	// initiate all fields in sensorList array to NULL
	for (int i = 0; i < MAX_SENSOR_COUNT; ++i) {
		_sensorList[i] = NULL;
	}

	// set flag: use multiplexed sensor or not?
	_useMultiplexer = useMultiplexer;
}

// Init new Tact Toolkit
void Tact::begin() {

	// Set up frequency generator
	TCCR1A = 0b10000010;
	TCCR1B = 0b00011001;

	// Signal generator pins
	pinMode (7, INPUT);
	pinMode (8, OUTPUT);
	// Sync (test) pin
	pinMode (9, OUTPUT);

	// Multiplexer pins
	if(_useMultiplexer) {
		pinMode (MP_4051_S0, OUTPUT);  // s0
		pinMode (MP_4051_S1, OUTPUT);  // s1
		pinMode (MP_4051_S2, OUTPUT);  // s2
	}
}

// Start Tact with Serial
void Tact::beginSerial(long br) {
	// Start up serial communication
  	Serial.begin(br);

  // flag needed for serial communication
	_runCMD = false;

	// run regular startup
	begin();
}

// Serial Event Delegation
void Tact::readSerial() {

	// While there is anything in the
	// pipe that has not been processed..
	while (Serial.available() > 0) {

		// Read incoming serial data
		byte inByte = Serial.read();

		switch (inByte) {
			case '\n':
				_runCMD = true;
				break;
			case CMD_SEPARATOR:
				// If token is command-separator: then increment
				// command-index to address the next field of
				// the command-buffer
				_serialCmdIndex++;
				break;
			// If none of the above
			default:
				// Test if byte represents a digit and
				// update existing int value
				if (inByte > 47 && inByte < 58) {
					_serialCmdBuffer[_serialCmdIndex] = _serialCmdBuffer[_serialCmdIndex] * 10 + (int) (inByte - 48);
					// If in range from A-Z
				} else if ( inByte > 64 && inByte < 123 ) {
	        // check if inByte in lowercase range (97-122)
	        if( inByte > 96) {
	          // transform to uppercase
	          inByte -= 32;
	        }

					// Set command key/name.
					_serialCmdKey = inByte;
					// reset the command-index to -1
					_serialCmdIndex = -1;
					// clear list of command parameters
					_serialCmdBuffer[0] = 0;
					_serialCmdBuffer[1] = 0;
					_serialCmdBuffer[2] = 0;
					_serialCmdBuffer[3] = 0;

					// stop cmd if there's more to come
					_runCMD = false;

				} else {
					// ERROR - unexpected token in parameter stream
				}
				break;
		}
	}

	// execute completed Serial command
	if( _runCMD ) {

		// Declare sensor value buffer
    int results[_serialCmdBuffer[CMD_BUFFER_COUNT]];
    // Declare peak and bias vars
    int peak = 0;
    int bias = 0;

		// command is not initial handshake
		if(_serialCmdKey  != 'V') {

			// using multiplex sensor?
			if(_useMultiplexer) {
				// Select the sensor-input / bit
	  		// (use this with arduino 0013+)
	    	digitalWrite (MP_4051_S0, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 0));
	    	digitalWrite (MP_4051_S1, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 1));
	    	digitalWrite (MP_4051_S2, bitRead (_serialCmdBuffer[CMD_BUFFER_PIN], 2));
	    }

	    for (unsigned int d = 0; d < _serialCmdBuffer[CMD_BUFFER_COUNT]; d++) {
	      // Reload new frequency
	      TCNT1 = 0;
	      ICR1 = _serialCmdBuffer[CMD_BUFFER_START] + _serialCmdBuffer[CMD_BUFFER_STEP] * d;
	      OCR1A = ICR1 / 2;

	      // Restart generator
	      SET (TCCR1B, 0);
	      // Read response signal
	      results[d] = (float) analogRead(0);
	      // Stop generator
	      CLR (TCCR1B, 0);

	      // Check if current result is higher than previously stored peak
	      // if true, overwrite peak and bias
	      if( results[d] > peak ) {
	        peak = results[d];
	        bias = d;
	      }
	    }

			// Announce which of the Tact-inputs that
    	// are multiplexed will be transmitted
    	_sendInt (1024 + _serialCmdBuffer[CMD_BUFFER_PIN]);
		}

		// act depending on command key
		switch (_serialCmdKey) {

			// transmit spectrum
			case 'S':
				// send data_type for data to be transmitted
        _sendInt( 1088 + 0 );
        // Tell client how many data values are going to be sent
       	_sendInt (1098 + _serialCmdBuffer[CMD_BUFFER_COUNT]);
        // Go! Send signal spectrum ...
        for (int x=0; x < _serialCmdBuffer[CMD_BUFFER_COUNT]; x++) {
        	_sendInt(results[x]);
       	}

				break;

			// transmit peak
			case 'P':
				// send data_type for data to be transmitted
	      _sendInt(1088 + 1);
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 1);
	      // send data
				_sendInt(peak);
				break;

			case 'B':
				// send data_type for data to be transmitted
	      _sendInt(1088 + 2);
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 1);
	      // send data
				_sendInt(bias);
				break;

			case 'X':
				// send data_type for data to be transmitted
	      _sendInt( 1088 + 3 );
	      // Tell client how many data values are going to be sent
	      _sendInt (1098 + 2);
	      // send bias
	      _sendInt(bias);
	      _sendInt(peak);
				break;

			case 'V':
				_sendInt (2124 + VERSION);
				break;

			default:
				; // do nothing
		}

		// command is not initial handshake
		if(_serialCmdKey  != 'V') {
			// Confirm that all data
		  // has been delivered, done!
		  _sendInt (2123);
		}

		_runCMD = false;
	}
}

// Helper to send integers via Serial
/* y = 01010100 11010100    (value is a 2 Byte integer)
 *     yMSB     yLSB        send seperately -> joined by client
 */
void Tact::_sendInt (unsigned int value) {
	Serial.write (byte(lowByte(value)));   // send Low Byte
	Serial.write (byte(highByte(value)));  // send high Byte
	// debug: print ints
	// Serial.println(value);
}

// Add single sensor with ID = 0
void Tact::addSensor(unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// add new sensor to sensor list
	_sensorList[0] = new TactSensor(0, _indexStart, _indexCount, _indexStep);
}

// Add Sensor with custom ID
void Tact::addSensor(unsigned int _sensorID, unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// add new sensor to sensor list
	_sensorList[_sensorID] = new TactSensor(_sensorID, _indexStart, _indexCount, _indexStep);
}

// read data from sensor and refresh data array of object TactSensor
void Tact::_refresh( TactSensor * sensor ) {

	// using multiplex sensor?
	if(_useMultiplexer) {
		// Select the sensor-input / bit
		// (use this with arduino 0013+)
		digitalWrite (MP_4051_S0, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 0));
		digitalWrite (MP_4051_S1, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 1));
		digitalWrite (MP_4051_S2, bitRead (sensor->cmdBuffer[CMD_BUFFER_PIN], 2));
	}

	// reset peak and bias to zero
	sensor->peak = 0;
	// sensor.bias = 0;

  for (unsigned int d = 0; d < sensor->cmdBuffer[CMD_BUFFER_COUNT]; d++) {
	// Reload new frequency
	TCNT1 = 0;
	ICR1 = sensor->cmdBuffer[CMD_BUFFER_START] + sensor->cmdBuffer[CMD_BUFFER_STEP] * d;
	OCR1A = ICR1 / 2;

	// Restart generator
	SET (TCCR1B, 0);

	// Read response signal and write to sensor data container
	sensor->data[d] = (float) analogRead(0);

	// Stop generator
	CLR (TCCR1B, 0);

	// Check if current result is higher than previously stored peak
	// if true, overwrite peak and bias
  	if( sensor->data[d] > sensor->peak ) {
  		// Serial.println(5);
		sensor->peak = sensor->data[d];
      	sensor->bias = d;
  	}

  }

  // Toggle pin 9 after each
	// sweep (good for scope)
	TOG (PORTB, 0);
}

int Tact::readPeak(unsigned int _sensorID) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// return refreshed bias
	return (*_sensorList[_sensorID]).peak;
}

// Tact:Read Bias
int Tact::readBias(unsigned int _sensorID) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// return refreshed bias
	return (*_sensorList[_sensorID]).bias;
}

// read Spectrum and write values to provided array
void Tact::readSpectrum(unsigned int _sensorID, int *targetArray) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[_sensorID] );
	// copy required amounts of integers from sensor data array to target array
	memcpy(targetArray, _sensorList[_sensorID]->data, _sensorList[_sensorID]->cmdBuffer[CMD_BUFFER_COUNT] * sizeof(int) );
}

// read Spectrum for single sensor and write values to provided array
void Tact::readSpectrum(int *targetArray) {
	// refresh sensor data for current sensor
	_refresh( _sensorList[0] );
	// work directly with retArray or memcpy into it from elsewhere like
  memcpy(targetArray, _sensorList[0]->data, _sensorList[0]->cmdBuffer[CMD_BUFFER_COUNT] * sizeof(int) );
}

// Constructor for TactSensor
Tact::TactSensor::TactSensor(unsigned int _id, unsigned int _indexStart, unsigned int _indexCount, unsigned int _indexStep) {
	// fill config array
	cmdBuffer[CMD_BUFFER_PIN] = _id;
	cmdBuffer[CMD_BUFFER_START] = _indexStart;
	cmdBuffer[CMD_BUFFER_COUNT] = _indexCount;
	cmdBuffer[CMD_BUFFER_STEP] = _indexStep;

	// fill variables
	peak = 0;
	bias = 0;
}

<|endoftext|>


<commit_before>#include "server/httplistener.h"
#include "common/config.h"

#include <Poco/Net/HTTPServer.h>
#include <Poco/Exception.h>

/*
 * http://www.codeproject.com/Articles/252827/Learning-Poco-A-simple-HTTP-server
 */

using namespace Batyr;

HttpListener::HttpListener(Configuration::Ptr _configuration)
    :   BaseListener(_configuration),
        logger(Poco::Logger::get("HttpListener")),
        isRunning(false)
{
    // prepare the server parameters and let them be managed by
    // a smart pointer
    auto serverParams = new Poco::Net::HTTPServerParams;
    serverParams->setMaxThreads( SERVER_HTTP_THREADS );
    serverParamsPtr.assign(serverParams);

    // set up the network socket
    try {
        socket.bind( configuration->getHttpPort() );
        socket.listen();
    }
    catch (Poco::Exception& e) {
        poco_error(logger, e.message());
        e.rethrow();
    }

    // will get destroyed with by the poco httpserver
    auto handlerFactory = new Batyr::HTTPRequestHandlerFactory(configuration);
    handlerFactoryPtr.assign(handlerFactory);

    server.reset(new Poco::Net::HTTPServer(handlerFactoryPtr, socket, serverParamsPtr));
}

HttpListener::~HttpListener()
{
    stop();
    socket.close();
}

void
HttpListener::run()
{
    poco_debug(logger, "Starting http listener");
    if (!isRunning) {

        // set the joblist
        handlerFactoryPtr->setJobs(jobs);

        server->start();
        isRunning = true;
    }
}

void
HttpListener::stop()
{
    poco_debug(logger, "Stopping http listener");
    if (isRunning) {
        server->stop();
        isRunning = false;
    }
}
<commit_msg>reuse server ports in httplistener to avoid "Adress already in use" errors<commit_after>#include "server/httplistener.h"
#include "common/config.h"

#include <Poco/Net/HTTPServer.h>
#include <Poco/Exception.h>

/*
 * http://www.codeproject.com/Articles/252827/Learning-Poco-A-simple-HTTP-server
 */

using namespace Batyr;

HttpListener::HttpListener(Configuration::Ptr _configuration)
    :   BaseListener(_configuration),
        logger(Poco::Logger::get("HttpListener")),
        isRunning(false)
{
    // prepare the server parameters and let them be managed by
    // a smart pointer
    serverParamsPtr.assign( new Poco::Net::HTTPServerParams );
    serverParamsPtr->setMaxThreads( SERVER_HTTP_THREADS );

    // set up the network socket
    try {
        // set reuse flags on the socket to prevent "Adress already in use"
        // errors on quick restarts of the server when the TCP socket
        // is still in TIME_WAIT state
        //socket.setReuseAddress(true);
        socket.setReusePort(true);

        socket.bind( configuration->getHttpPort() );
        socket.listen();
    }
    catch (Poco::Exception& e) {
        poco_error(logger, e.message());
        e.rethrow();
    }

    // will get destroyed with by the poco httpserver
    handlerFactoryPtr.assign( new Batyr::HTTPRequestHandlerFactory(configuration) );

    server.reset(new Poco::Net::HTTPServer(handlerFactoryPtr, socket, serverParamsPtr));
}

HttpListener::~HttpListener()
{
    stop();
    socket.close();
}

void
HttpListener::run()
{
    poco_debug(logger, "Starting http listener");
    if (!isRunning) {

        // set the joblist
        handlerFactoryPtr->setJobs(jobs);

        server->start();
        isRunning = true;
    }
}

void
HttpListener::stop()
{
    poco_debug(logger, "Stopping http listener");
    if (isRunning) {
        server->stop();
        isRunning = false;
    }
}
<|endoftext|>


<commit_before>/* TRANS - transpose a mono input signal using cubic spline interpolation

   p0 = output start time
   p1 = input start time
   p2 = output duration (time to end if negative)
   p3 = amplitude multiplier
   p4 = interval of transposition, in octave.pc
   p5 = input channel [optional, default is 0]
   p6 = percent to left [optional, default is .5]

   Processes only one channel at a time.

   Assumes function table 1 is amplitude curve for the note.
   You can call setline for this.

   TRANS was written by Doug Scott.
   Revised by John Gibson <johngibson@virginia.edu>, 2/29/00.
*/
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <mixerr.h>
#include "TRANS.h"
#include <rt.h>

//#define DEBUG

extern "C" {
   #include <ugens.h>
   extern int resetval;
}

static float interp(float, float, float, float);

TRANS :: TRANS() : Instrument()
{
   in = new float[MAXBUF + (MAXCHANS * 2)];
   out = new float[MAXBUF];

   inframe = RTBUFSAMPS;
   incount = 0;
   counter = 0.0;
   getflag = 1;
   first_time = 1;

   /* clear sample history */
   oldersig = 0.0;
   oldsig = 0.0;
   newsig = 0.0;
}

TRANS :: ~TRANS()
{
   delete [] in;
   delete [] out;
}

int TRANS :: init(float p[], short n_args)
{
   float outskip, inskip, dur, transp, interval;

   if (n_args < 5) {
      cerr << "TRANS: Wrong number of args." << endl;
      return -1;
   }
   outskip = p[0];
   inskip = p[1];
   dur = p[2];
   amp = p[3];
   transp = p[4];
   inchan = (n_args > 5) ? (int) p[5] : 0;
   pctleft = (n_args > 6) ? p[6] : 0.5;

   if (dur < 0.0)
      dur = -dur - inskip;

   nsamps = rtsetoutput(outskip, dur, this);
   rtsetinput(inskip, this);

   interval = octpch(transp);
   increment = (double) cpsoct(10.0 + interval) / cpsoct(10.0);
#ifdef DEBUG
   printf("increment: %g\n", increment);
#endif

   amptable = floc(1);
   if (amptable) {
      int amplen = fsize(1);
      tableset(p[2], amplen, tabs);
   }
   else
      printf("Setting phrase curve to all 1's\n");

   skip = (int) (SR / (float) resetval);

   return nsamps;
}

inline int min(int x, int y)
{
   if (x < y)
      return x;
   else
      return y;
}

int TRANS :: run()
{
   const int outframes = chunksamps;
   int       i;
   int       branch = 0;
   float     aamp;
   float     *outp = out;

   aamp = amp;                  /* in case amptable == NULL */

   if (first_time) {
      inframe = outframes;
      first_time = 0;
   }

   for (i = 0; i < outframes; i++) {
      if (--branch < 0) {
         if (amptable)
            aamp = table(cursamp, amptable, tabs) * amp;
         branch = skip;
      }
      while (getflag) {
         int index;

         if (inframe == outframes) {          /* time for an input buffer */
            rtgetin(in, this, inputchans * outframes);
#ifdef DEBUG
            printf("READ %d frames\n", outframes);
#endif
            inframe = 0;
         }
         oldersig = oldsig;
         oldsig = newsig;

         index = inframe * inputchans;
         newsig = in[index + inchan];

         incount++;
         inframe++;
         if (counter - (double) incount < 0.5)
            getflag = 0;
      }

      double frac = counter - (double) incount + 2.0;
      outp[0] = interp(oldersig, oldsig, newsig, frac) * aamp;
#ifdef DEBUG
      printf("i: %d counter: %g incount: %d frac: %g inframe: %d cursamp: %d\n",
             i, counter, incount, frac, inframe, cursamp);
      printf("interping %g, %g, %g\n", oldersig, oldsig, newsig);
#endif

      if (NCHANS == 2) {
         outp[1] = outp[0] * (1.0 - pctleft);
         outp[0] *= pctleft;
      }

      outp += NCHANS;
      cursamp++;

      counter += increment;     // keeps track of interp pointer
      if (counter - (double) incount >= -0.5)
         getflag = 1;
   }

   rtbaddout(out, outframes * NCHANS);
#ifdef DEBUG
   printf("OUT %d samples\n\n", i);
#endif

   return i;
}

Instrument *makeTRANS()
{
   return new TRANS();
}

void rtprofile()
{
   RT_INTRO("TRANS", makeTRANS);
}

static float interp(float y0, float y1, float y2, float t)
{
   float hy2, hy0, a, b, c;

   a = y0;
   hy0 = y0 / 2.0f;
   hy2 = y2 / 2.0f;
   b = (-3.0f * hy0) + (2.0f * y1) - hy2;
   c = hy0 - y1 + hy2;

   return (a + b * t + c * t * t);
}

<commit_msg>Rev'd for v2.3.<commit_after>/* TRANS - transpose a mono input signal using cubic spline interpolation

   p0 = output start time
   p1 = input start time
   p2 = output duration (time to end if negative)
   p3 = amplitude multiplier
   p4 = interval of transposition, in octave.pc
   p5 = input channel [optional, default is 0]
   p6 = percent to left [optional, default is .5]

   Processes only one channel at a time.

   Assumes function table 1 is amplitude curve for the note.
   You can call setline for this.

   TRANS was written by Doug Scott.
   Revised by John Gibson <johngibson@virginia.edu>, 2/29/00.
*/
#include <stdio.h>
#include <stdlib.h>
#include <mixerr.h>
#include "TRANS.h"
#include <rt.h>

//#define DEBUG

extern "C" {
   #include <ugens.h>
   extern int resetval;
}

static float interp(float, float, float, float);

TRANS :: TRANS() : Instrument()
{
   in = new float[MAXBUF];       /* MUST persist across calls to run() */

   inframe = RTBUFSAMPS;
   incount = 0;
   counter = 0.0;
   getflag = 1;
   first_time = 1;

   /* clear sample history */
   oldersig = 0.0;
   oldsig = 0.0;
   newsig = 0.0;
}

TRANS :: ~TRANS()
{
   delete [] in;
}

int TRANS :: init(float p[], short n_args)
{
   float outskip, inskip, dur, transp, interval;

   if (n_args < 5) {
      fprintf(stderr, "TRANS: Wrong number of args.\n");
      exit(1);
   }
   outskip = p[0];
   inskip = p[1];
   dur = p[2];
   amp = p[3];
   transp = p[4];
   inchan = (n_args > 5) ? (int) p[5] : 0;
   pctleft = (n_args > 6) ? p[6] : 0.5;

   if (dur < 0.0)
      dur = -dur - inskip;

   nsamps = rtsetoutput(outskip, dur, this);
   rtsetinput(inskip, this);

   if (inchan >= inputchans) {
      fprintf(stderr, "TRANS: You asked for channel %d of a %d-channel file.\n",
                      inchan, inputchans);
      exit(1);
   }

   interval = octpch(transp);
   increment = (double) cpsoct(10.0 + interval) / cpsoct(10.0);
#ifdef DEBUG
   printf("increment: %g\n", increment);
#endif

   amptable = floc(1);
   if (amptable) {
      int amplen = fsize(1);
      tableset(p[2], amplen, tabs);
   }
   else
      printf("Setting phrase curve to all 1's\n");

   skip = (int) (SR / (float) resetval);

   return nsamps;
}

inline int min(int x, int y)
{
   if (x < y)
      return x;
   else
      return y;
}

int TRANS :: run()
{
   const int outframes = chunksamps;
   int       i;
   int       branch = 0;
   float     aamp;
   float     *outp;

   Instrument :: run();

   outp = outbuf;               /* point to inst private out buffer */

   aamp = amp;                  /* in case amptable == NULL */

   if (first_time) {
      inframe = outframes;
      first_time = 0;
   }

   for (i = 0; i < outframes; i++) {
      if (--branch < 0) {
         if (amptable)
            aamp = table(cursamp, amptable, tabs) * amp;
         branch = skip;
      }
      while (getflag) {
         int index;

         if (inframe == outframes) {          /* time for an input buffer */
            rtgetin(in, this, inputchans * outframes);
#ifdef DEBUG
            printf("READ %d frames\n", outframes);
#endif
            inframe = 0;
         }
         oldersig = oldsig;
         oldsig = newsig;

         index = inframe * inputchans;
         newsig = in[index + inchan];

         incount++;
         inframe++;
         if (counter - (double) incount < 0.5)
            getflag = 0;
      }

      double frac = counter - (double) incount + 2.0;
      outp[0] = interp(oldersig, oldsig, newsig, frac) * aamp;
#ifdef DEBUG
      printf("i: %d counter: %g incount: %d frac: %g inframe: %d cursamp: %d\n",
             i, counter, incount, frac, inframe, cursamp);
      printf("interping %g, %g, %g\n", oldersig, oldsig, newsig);
#endif

      if (outputchans == 2) {
         outp[1] = outp[0] * (1.0 - pctleft);
         outp[0] *= pctleft;
      }

      outp += outputchans;
      cursamp++;

      counter += increment;     // keeps track of interp pointer
      if (counter - (double) incount >= -0.5)
         getflag = 1;
   }

#ifdef DEBUG
   printf("OUT %d samples\n\n", i);
#endif

   return i;
}

Instrument *makeTRANS()
{
   TRANS *inst;

   inst = new TRANS();
   inst->set_bus_config("TRANS");

   return inst;
}

void rtprofile()
{
   RT_INTRO("TRANS", makeTRANS);
}

static float interp(float y0, float y1, float y2, float t)
{
   float hy2, hy0, a, b, c;

   a = y0;
   hy0 = y0 / 2.0f;
   hy2 = y2 / 2.0f;
   b = (-3.0f * hy0) + (2.0f * y1) - hy2;
   c = hy0 - y1 + hy2;

   return (a + b * t + c * t * t);
}

<|endoftext|>