<commit_before>//----------------------------  data_out.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  data_out.cc  ---------------------------

#include <base/quadrature_lib.h>
#include <lac/vector.h>
#include <numerics/data_out.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <grid/tria_iterator.h>
#include <fe/fe.h>
#include <fe/fe_values.h>

#ifdef DEAL_II_USE_MT
#include <base/thread_manager.h>
#endif

template <int dim>
DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
					    const vector<string> &names) :
		data(data),
		names(names)
{};

template <int dim>
DataOut_DoFData<dim>::DataOut_DoFData () :
		dofs(0)
{};

template <int dim>
DataOut_DoFData<dim>::~DataOut_DoFData ()
{
  clear ();
};

template <int dim>
void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
{
  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
  Assert (cell_data.size() == 0, ExcOldDataStillPresent());

  if (dofs != 0)
    dofs->unsubscribe ();

  dofs = &d;
  if (dofs != 0)
    dofs->subscribe ();
};

template <int dim>
void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
					    const vector<string> &names)
{
  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
				   // either cell data and one name,
				   // or dof data and n_components names
  Assert (((vec.size() == dofs->get_tria().n_active_cells()) &&
	   (names.size() == 1))
	  ||
	  ((vec.size() == dofs->n_dofs()) &&
	   (names.size() == dofs->get_fe().n_components())),
	  ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
  for (unsigned int i=0; i<names.size(); ++i)
    Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
				       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
				       "0123456789_<>()") == string::npos,
	    ExcInvalidCharacter (names[i]));

  DataEntry new_entry (&vec, names);
  if (vec.size() == dofs->n_dofs())
    dof_data.push_back (new_entry);
  else
    if (vec.size() == dofs->get_tria().n_active_cells())
      cell_data.push_back (new_entry);
    else
      Assert (false,
	      ExcInvalidVectorSize (vec.size(),
				    dofs->n_dofs(),
				    dofs->get_tria().n_active_cells()));
};

template <int dim>
void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
					    const string         &name)
{
//  unsigned int n = dofs->get_fe().n_components ();
//    if (n > 1)
//      {
//        vector<string> names (dofs->get_fe().n_components ());
//        for (unsigned int i=0;i<n;++i)
//  	{
//  	  names[i] = name + string("_");
//  	}
//    }
//TODO: Murks hier
  add_data_vector (vec, vector<string>(1,name));
}

template <int dim>
void DataOut_DoFData<dim>::clear ()
{
  dof_data.erase (dof_data.begin(), dof_data.end());
  cell_data.erase (cell_data.begin(), cell_data.end());

  if (dofs != 0)
    {
      dofs->unsubscribe ();
      dofs = 0;
    };

				   // delete patches
  vector<DataOutBase::Patch<dim> > dummy;
  patches.swap (dummy);
};

template <int dim>
vector<string> DataOut_DoFData<dim>::get_dataset_names () const
{
  vector<string> names;
				   // collect the names of dof
				   // and cell data
  for (vector<DataEntry>::const_iterator d=dof_data.begin(); d!=dof_data.end(); ++d)
    for (unsigned int i=0; i<d->names.size(); ++i)
      names.push_back (d->names[i]);
  for (vector<DataEntry>::const_iterator d=cell_data.begin(); d!=cell_data.end(); ++d)
    {
      Assert (d->names.size() == 1, ExcInternalError());
      names.push_back (d->names[0]);
    };

  return names;
};

template <int dim>
const vector<typename DataOutBase::Patch<dim> > &
DataOut_DoFData<dim>::get_patches () const
{
  return patches;
};

template <int dim>
void DataOut<dim>::build_some_patches (Data data)
{
  QTrapez<1>     q_trapez;
  QIterated<dim> patch_points (q_trapez, data.n_subdivisions);

  FEValues<dim> fe_patch_values(dofs->get_fe(),
				patch_points,
				update_default);

  const unsigned int n_q_points = patch_points.n_quadrature_points;

  unsigned int cell_number = 0;
  vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
  DoFHandler<dim>::cell_iterator cell=first_cell();

				   // get first cell in this thread
  for (unsigned int i=0;i<data.this_thread;++i,++patch,++cell_number,
		 cell=next_cell(cell));

  				   // now loop over all cells and
				   // actually create the patches
  for (;cell != dofs->end();)
    {
      Assert (patch != patches.end(), ExcInternalError());

      for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
	patch->vertices[vertex] = cell->vertex(vertex);

      if (data.n_datasets > 0)
	{
	  fe_patch_values.reinit (cell);

					   // first fill dof_data
	  for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
	    {
	      if (data.n_components == 1)
		{
		  fe_patch_values.get_function_values (*dof_data[dataset].data,
						       data.patch_values);
		  for (unsigned int q=0; q<n_q_points; ++q)
		    patch->data(dataset,q) = data.patch_values[q];
		}
	      else
						 // system of components
		{
		  fe_patch_values.get_function_values (*dof_data[dataset].data,
						       data.patch_values_system);
		  for (unsigned int component=0; component<data.n_components;
		       ++component)
		    for (unsigned int q=0; q<n_q_points; ++q)
		      patch->data(dataset*data.n_components+component,q) =
			data.patch_values_system[q](component);
		};
	    };

					   // then do the cell data
	  for (unsigned int dataset=0; dataset<cell_data.size(); ++dataset)
	    {
	      const double value = (*cell_data[dataset].data)(cell_number);
	      for (unsigned int q=0; q<n_q_points; ++q)
		patch->data(dataset+dof_data.size()*data.n_components,q) =
		  value;
	    };
	};
      				       // next cell (patch) in this thread
      for (unsigned int i=0;((i<data.n_threads)&&(cell != dofs->end()));
	   ++i,++patch,++cell_number,cell=next_cell(cell));

    };
}

template <int dim>
void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
				  const unsigned int n_threads_)
{
  Assert (dofs != 0, ExcNoDoFHandlerSelected());

#ifdef DEAL_II_USE_MT
  const unsigned int n_threads = n_threads_;
#else
  const unsigned int n_threads = 1;
#endif

// before we start the loop:
				   // create a quadrature rule that
				   // actually has the points on this
				   // patch
  QTrapez<1>     q_trapez;
  QIterated<dim> patch_points (q_trapez, n_subdivisions);

  const unsigned int n_q_points     = patch_points.n_quadrature_points;
  const unsigned int n_components   = dofs->get_fe().n_components();
  const unsigned int n_datasets     = dof_data.size() * n_components +
				      cell_data.size();

				   // clear the patches array
  if (true)
    {
      vector<DataOutBase::Patch<dim> > dummy;
      patches.swap (dummy);
    };

				   // first count the cells we want to
				   // create patches of and make sure
				   // there is enough memory for that
  unsigned int n_patches = 0;
  for (DoFHandler<dim>::cell_iterator cell=first_cell();
       cell != dofs->end();
       cell = next_cell(cell))
    ++n_patches;

  vector<Data> thread_data(n_threads);

				   // init data for the threads
  for (unsigned int i=0;i<n_threads;++i)
    {
      thread_data[i].n_threads      = n_threads;
      thread_data[i].this_thread    = i;
      thread_data[i].n_components   = n_components;
      thread_data[i].n_datasets     = n_datasets;
      thread_data[i].n_subdivisions = n_subdivisions;
      thread_data[i].patch_values.resize (n_q_points);
      thread_data[i].patch_values_system.resize (n_q_points);

      for (unsigned int k=0; k<n_q_points; ++k)
	thread_data[i].patch_values_system[k].reinit(n_components);
    }

				   // create the patches with
				   // default values
  DataOutBase::Patch<dim>  default_patch;
  default_patch.n_subdivisions = n_subdivisions;
  default_patch.data.reinit (n_datasets, n_q_points);
  patches.insert (patches.end(), n_patches, default_patch);

#ifdef DEAL_II_USE_MT

  ThreadManager thread_manager;

  typedef ThreadManager::Mem_Fun_Data1
    <DataOut<dim>, Data> MemFunData;

				   // One struct of this type for every thread
  vector<MemFunData> mem_fun_data (n_threads,
				   MemFunData (this,
					       thread_data[0],
					       &DataOut<dim>::build_some_patches));

				   // get start cells for each thread
  for (unsigned int l=0;l<n_threads;++l)
    {
      mem_fun_data[l].arg=thread_data[l];
      thread_manager.spawn(&mem_fun_data[l],THR_SCOPE_SYSTEM | THR_DETACHED);
    };
				   // wait for all threads to return
  thread_manager.wait();

				   // just one thread
#else
  build_some_patches(thread_data[0]);
#endif
};

template <int dim>
typename DoFHandler<dim>::cell_iterator
DataOut<dim>::first_cell ()
{
  return dofs->begin_active ();
};

template <int dim>
typename DoFHandler<dim>::cell_iterator
DataOut<dim>::next_cell (const typename DoFHandler<dim>::cell_iterator &cell)
{
				   // convert the iterator to an
				   // active_iterator and advance
				   // this to the next active cell
  typename DoFHandler<dim>::active_cell_iterator active_cell = cell;
  ++active_cell;
  return active_cell;
};

// explicit instantiations
template class DataOut_DoFData<deal_II_dimension>;
template class DataOut<deal_II_dimension>;

<commit_msg>Avoid compiler warning.<commit_after>//----------------------------  data_out.cc  ---------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  data_out.cc  ---------------------------

#include <base/quadrature_lib.h>
#include <lac/vector.h>
#include <numerics/data_out.h>
#include <grid/tria.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <grid/tria_iterator.h>
#include <fe/fe.h>
#include <fe/fe_values.h>

#ifdef DEAL_II_USE_MT
#include <base/thread_manager.h>
#endif

template <int dim>
DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
					    const vector<string> &names) :
		data(data),
		names(names)
{};

template <int dim>
DataOut_DoFData<dim>::DataOut_DoFData () :
		dofs(0)
{};

template <int dim>
DataOut_DoFData<dim>::~DataOut_DoFData ()
{
  clear ();
};

template <int dim>
void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
{
  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
  Assert (cell_data.size() == 0, ExcOldDataStillPresent());

  if (dofs != 0)
    dofs->unsubscribe ();

  dofs = &d;
  if (dofs != 0)
    dofs->subscribe ();
};

template <int dim>
void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
					    const vector<string> &names)
{
  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
				   // either cell data and one name,
				   // or dof data and n_components names
  Assert (((vec.size() == dofs->get_tria().n_active_cells()) &&
	   (names.size() == 1))
	  ||
	  ((vec.size() == dofs->n_dofs()) &&
	   (names.size() == dofs->get_fe().n_components())),
	  ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components()));
  for (unsigned int i=0; i<names.size(); ++i)
    Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
				       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
				       "0123456789_<>()") == string::npos,
	    ExcInvalidCharacter (names[i]));

  DataEntry new_entry (&vec, names);
  if (vec.size() == dofs->n_dofs())
    dof_data.push_back (new_entry);
  else
    if (vec.size() == dofs->get_tria().n_active_cells())
      cell_data.push_back (new_entry);
    else
      Assert (false,
	      ExcInvalidVectorSize (vec.size(),
				    dofs->n_dofs(),
				    dofs->get_tria().n_active_cells()));
};

template <int dim>
void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
					    const string         &name)
{
//  unsigned int n = dofs->get_fe().n_components ();
//    if (n > 1)
//      {
//        vector<string> names (dofs->get_fe().n_components ());
//        for (unsigned int i=0;i<n;++i)
//  	{
//  	  names[i] = name + string("_");
//  	}
//    }
//TODO: Murks hier
  add_data_vector (vec, vector<string>(1,name));
}

template <int dim>
void DataOut_DoFData<dim>::clear ()
{
  dof_data.erase (dof_data.begin(), dof_data.end());
  cell_data.erase (cell_data.begin(), cell_data.end());

  if (dofs != 0)
    {
      dofs->unsubscribe ();
      dofs = 0;
    };

				   // delete patches
  vector<DataOutBase::Patch<dim> > dummy;
  patches.swap (dummy);
};

template <int dim>
vector<string> DataOut_DoFData<dim>::get_dataset_names () const
{
  vector<string> names;
				   // collect the names of dof
				   // and cell data
  for (vector<DataEntry>::const_iterator d=dof_data.begin(); d!=dof_data.end(); ++d)
    for (unsigned int i=0; i<d->names.size(); ++i)
      names.push_back (d->names[i]);
  for (vector<DataEntry>::const_iterator d=cell_data.begin(); d!=cell_data.end(); ++d)
    {
      Assert (d->names.size() == 1, ExcInternalError());
      names.push_back (d->names[0]);
    };

  return names;
};

template <int dim>
const vector<typename DataOutBase::Patch<dim> > &
DataOut_DoFData<dim>::get_patches () const
{
  return patches;
};

template <int dim>
void DataOut<dim>::build_some_patches (Data data)
{
  QTrapez<1>     q_trapez;
  QIterated<dim> patch_points (q_trapez, data.n_subdivisions);

  FEValues<dim> fe_patch_values(dofs->get_fe(),
				patch_points,
				update_default);

  const unsigned int n_q_points = patch_points.n_quadrature_points;

  unsigned int cell_number = 0;
  vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
  DoFHandler<dim>::cell_iterator cell=first_cell();

				   // get first cell in this thread
  for (unsigned int i=0;i<data.this_thread;++i,++patch,++cell_number,
		 cell=next_cell(cell));

  				   // now loop over all cells and
				   // actually create the patches
  for (;cell != dofs->end();)
    {
      Assert (patch != patches.end(), ExcInternalError());

      for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
	patch->vertices[vertex] = cell->vertex(vertex);

      if (data.n_datasets > 0)
	{
	  fe_patch_values.reinit (cell);

					   // first fill dof_data
	  for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
	    {
	      if (data.n_components == 1)
		{
		  fe_patch_values.get_function_values (*dof_data[dataset].data,
						       data.patch_values);
		  for (unsigned int q=0; q<n_q_points; ++q)
		    patch->data(dataset,q) = data.patch_values[q];
		}
	      else
						 // system of components
		{
		  fe_patch_values.get_function_values (*dof_data[dataset].data,
						       data.patch_values_system);
		  for (unsigned int component=0; component<data.n_components;
		       ++component)
		    for (unsigned int q=0; q<n_q_points; ++q)
		      patch->data(dataset*data.n_components+component,q) =
			data.patch_values_system[q](component);
		};
	    };

					   // then do the cell data
	  for (unsigned int dataset=0; dataset<cell_data.size(); ++dataset)
	    {
	      const double value = (*cell_data[dataset].data)(cell_number);
	      for (unsigned int q=0; q<n_q_points; ++q)
		patch->data(dataset+dof_data.size()*data.n_components,q) =
		  value;
	    };
	};
      				       // next cell (patch) in this thread
      for (unsigned int i=0;((i<data.n_threads)&&(cell != dofs->end()));
	   ++i,++patch,++cell_number,cell=next_cell(cell));

    };
}

template <int dim>
void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
				  const unsigned int n_threads_)
{
  Assert (dofs != 0, ExcNoDoFHandlerSelected());

#ifdef DEAL_II_USE_MT
  const unsigned int n_threads = n_threads_;
#else
				   // access this variable to avoid
				   // compiler warning about unused
				   // var:
  (void)n_threads_;
  const unsigned int n_threads = 1;
#endif

// before we start the loop:
				   // create a quadrature rule that
				   // actually has the points on this
				   // patch
  QTrapez<1>     q_trapez;
  QIterated<dim> patch_points (q_trapez, n_subdivisions);

  const unsigned int n_q_points     = patch_points.n_quadrature_points;
  const unsigned int n_components   = dofs->get_fe().n_components();
  const unsigned int n_datasets     = dof_data.size() * n_components +
				      cell_data.size();

				   // clear the patches array
  if (true)
    {
      vector<DataOutBase::Patch<dim> > dummy;
      patches.swap (dummy);
    };

				   // first count the cells we want to
				   // create patches of and make sure
				   // there is enough memory for that
  unsigned int n_patches = 0;
  for (DoFHandler<dim>::cell_iterator cell=first_cell();
       cell != dofs->end();
       cell = next_cell(cell))
    ++n_patches;

  vector<Data> thread_data(n_threads);

				   // init data for the threads
  for (unsigned int i=0;i<n_threads;++i)
    {
      thread_data[i].n_threads      = n_threads;
      thread_data[i].this_thread    = i;
      thread_data[i].n_components   = n_components;
      thread_data[i].n_datasets     = n_datasets;
      thread_data[i].n_subdivisions = n_subdivisions;
      thread_data[i].patch_values.resize (n_q_points);
      thread_data[i].patch_values_system.resize (n_q_points);

      for (unsigned int k=0; k<n_q_points; ++k)
	thread_data[i].patch_values_system[k].reinit(n_components);
    }

				   // create the patches with
				   // default values
  DataOutBase::Patch<dim>  default_patch;
  default_patch.n_subdivisions = n_subdivisions;
  default_patch.data.reinit (n_datasets, n_q_points);
  patches.insert (patches.end(), n_patches, default_patch);

#ifdef DEAL_II_USE_MT

  ThreadManager thread_manager;

  typedef ThreadManager::Mem_Fun_Data1
    <DataOut<dim>, Data> MemFunData;

				   // One struct of this type for every thread
  vector<MemFunData> mem_fun_data (n_threads,
				   MemFunData (this,
					       thread_data[0],
					       &DataOut<dim>::build_some_patches));

				   // get start cells for each thread
  for (unsigned int l=0;l<n_threads;++l)
    {
      mem_fun_data[l].arg=thread_data[l];
      thread_manager.spawn(&mem_fun_data[l],THR_SCOPE_SYSTEM | THR_DETACHED);
    };
				   // wait for all threads to return
  thread_manager.wait();

				   // just one thread
#else
  build_some_patches(thread_data[0]);
#endif
};

template <int dim>
typename DoFHandler<dim>::cell_iterator
DataOut<dim>::first_cell ()
{
  return dofs->begin_active ();
};

template <int dim>
typename DoFHandler<dim>::cell_iterator
DataOut<dim>::next_cell (const typename DoFHandler<dim>::cell_iterator &cell)
{
				   // convert the iterator to an
				   // active_iterator and advance
				   // this to the next active cell
  typename DoFHandler<dim>::active_cell_iterator active_cell = cell;
  ++active_cell;
  return active_cell;
};

// explicit instantiations
template class DataOut_DoFData<deal_II_dimension>;
template class DataOut<deal_II_dimension>;

<|endoftext|>


<commit_before>
/*
  Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.6

  Original library                  (0.1) by Tom Igoe.
  Two-wire modifications            (0.2) by Sebastian Gassner
  Combination version               (0.3) by Tom Igoe and David Mellis
  Bug fix for four-wire             (0.4) by Tom Igoe, bug fix from Noah Shibley
  Wave step mode for 4 wire systems (0.5) by Geoff Day
  Sleep mode for 4 wire systems     (0.6) by Geoff Day

  Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires
  When wiring multiple stepper motors to a microcontroller,
  you quickly run out of output pins, with each motor requiring 4 connections.
  By making use of the fact that at any time two of the four motor
  coils are the inverse  of the other two, the number of
  control connections can be reduced from 4 to 2.
  A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
  connects to only 2 microcontroler pins, inverts the signals received,
  and delivers the 4 (2 plus 2 inverted ones) output signals required
  for driving a stepper motor.
  The sequence of control signals for 4 control wires is as follows:
  Step C0 C1 C2 C3
     1  1  0  1  0
     2  0  1  1  0
     3  0  1  0  1
     4  1  0  0  1
  The sequence of controls signals for 2 control wires is as follows
  (columns C1 and C2 from above):
  Step C0 C1
     1  0  1
     2  1  1
     3  1  0
     4  0  0
  The circuits can be found at
  http://www.arduino.cc/en/Tutorial/Stepper

  The Wave step sequence of control signals for 4 control wires is as follows:
  Step C0 C1 C2 C3
     1  1  0  0  0
     2  0  0  1  0
     3  0  1  0  0
     4  0  0  0  1

  Good for lower power operation where lower torque is ok.
  sleep mode when high sends all outputs low. No holding torque!
 */

#include "application.h"
#include "Stepper.h"

/*
 * two-wire constructor.
 * Sets which wires should control the motor.
 */
Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
{
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;        // the motor speed, in revolutions per minute
  this->direction = 0;      // motor direction
  this->last_step_time = 0;    // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor

  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);

  // When there are only 2 pins, set the other two to 0:
  this->motor_pin_3 = 0;
  this->motor_pin_4 = 0;

  // pin_count is used by the stepMotor() method:
  this->pin_count = 2;
}

/*
 *   constructor for four-pin version
 *   Sets which wires should control the motor.
 */

Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4)
{
  this->sleep = 0;    // default to 0 - no sleeping. 1 to sleep. All output drives to zero so no holding torque!
  this->mode = 0;     // full step mode = 0
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;            // the motor speed, in revolutions per minute
  this->direction = 0;        // motor direction
  this->last_step_time = 0;   // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor

  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
  this->motor_pin_3 = motor_pin_3;
  this->motor_pin_4 = motor_pin_4;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  pinMode(this->motor_pin_3, OUTPUT);
  pinMode(this->motor_pin_4, OUTPUT);

  // pin_count is used by the stepMotor() method:
  this->pin_count = 4;
}

/*
  set to sleep mode for lower power consumption. Only valid in 4 wire mode.
  Remember there's no holding torque!!!
*/

  void Stepper::setSleep(int sleep)
  {
    this->sleep = sleep;

    if (this->sleep == 1) {
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, LOW);
      digitalWrite(motor_pin_3, LOW);
      digitalWrite(motor_pin_4, LOW);
    } else {
      stepMotor(this->step_number % 4);
    }
  }

/*
  set stepper mode, full or wave currently. Wave mode for low power applications.
  only applicable in 4 wire setups.
*/

  void Stepper::setMode(int mode)
  {
    this->mode = mode;
  }

/*
  Sets the speed in revs per minute

*/
void Stepper::setSpeed(long whatSpeed)
{
  this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
}

/*
  Moves the motor steps_to_move steps.  If the number is negative,
   the motor moves in the reverse direction.
 */
void Stepper::step(int steps_to_move)
{
  int steps_left = abs(steps_to_move);  // how many steps to take

  // determine direction based on whether steps_to_mode is + or -:
  if (steps_to_move > 0) {this->direction = 1;}
  if (steps_to_move < 0) {this->direction = 0;}

  // decrement the number of steps, moving one step each time:
  while(steps_left > 0) {
  // move only if the appropriate delay has passed:
  if (millis() - this->last_step_time >= this->step_delay) {
      // get the timeStamp of when you stepped:
      this->last_step_time = millis();
      // increment or decrement the step number,
      // depending on direction:
      if (this->direction == 1) {
        this->step_number++;
        if (this->step_number == this->number_of_steps) {
          this->step_number = 0;
        }
      }
      else {
        if (this->step_number == 0) {
          this->step_number = this->number_of_steps;
        }
        this->step_number--;
      }
      // decrement the steps left:
      steps_left--;
      // step the motor to step number 0, 1, 2, or 3:
      stepMotor(this->step_number % 4);
    }
  }
}

/*
 * Moves the motor forward or backwards.
 */
void Stepper::stepMotor(int thisStep)
{
  if (this->pin_count == 2) {
    switch (thisStep) {
      case 0: /* 01 */
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 1: /* 11 */
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 2: /* 10 */
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
      break;
      case 3: /* 00 */
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, LOW);
      break;
    }
  }
  if (this->pin_count == 4) {
    switch (thisStep) {
      case 0:    // 1010
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_3, LOW);
        } else {
          digitalWrite(motor_pin_3, HIGH);
        }
        digitalWrite(motor_pin_4, LOW);
      break;
      case 1:    // 0110
        digitalWrite(motor_pin_1, LOW);
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_2, LOW);
        } else {
          digitalWrite(motor_pin_2, HIGH);
        }
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
      break;
      case 2:    //0101
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        // mode high for wave step
        if (this->mode) {
            digitalWrite(motor_pin_4, LOW);
        } else {
            digitalWrite(motor_pin_4, HIGH);
        }
      break;
      case 3:    //1001
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_1, LOW);
        } else {
          digitalWrite(motor_pin_1, HIGH);
        }
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
      break;
    }
  }
}

/*
  version() returns the version of the library:
*/
int Stepper::version(void)
{
  return 6;
}
<commit_msg>Update Stepper.cpp<commit_after>
/*
  Stepper.cpp - - Stepper library for Wiring/Arduino - Version 0.6

  Original library                  (0.1) by Tom Igoe.
  Two-wire modifications            (0.2) by Sebastian Gassner
  Combination version               (0.3) by Tom Igoe and David Mellis
  Bug fix for four-wire             (0.4) by Tom Igoe, bug fix from Noah Shibley
  Wave step mode for 4 wire systems (0.5) by Geoff Day
  Sleep mode for 4 wire systems     (0.6) by Geoff Day

  Drives a unipolar or bipolar stepper motor using  2 wires or 4 wires
  When wiring multiple stepper motors to a microcontroller,
  you quickly run out of output pins, with each motor requiring 4 connections.
  By making use of the fact that at any time two of the four motor
  coils are the inverse  of the other two, the number of
  control connections can be reduced from 4 to 2.
  A slightly modified circuit around a Darlington transistor array or an L293 H-bridge
  connects to only 2 microcontroler pins, inverts the signals received,
  and delivers the 4 (2 plus 2 inverted ones) output signals required
  for driving a stepper motor.
  The sequence of control signals for 4 control wires is as follows:
  Step C0 C1 C2 C3
     1  1  0  1  0
     2  0  1  1  0
     3  0  1  0  1
     4  1  0  0  1
  The sequence of controls signals for 2 control wires is as follows
  (columns C1 and C2 from above):
  Step C0 C1
     1  0  1
     2  1  1
     3  1  0
     4  0  0
  The circuits can be found at
  http://www.arduino.cc/en/Tutorial/Stepper

  The Wave step sequence of control signals for 4 control wires is as follows:
  Step C0 C1 C2 C3
     1  1  0  0  0
     2  0  0  1  0
     3  0  1  0  0
     4  0  0  0  1

  Good for lower power operation where lower torque is ok.
  sleep mode when high sends all outputs low. No holding torque!
 */

#include "application.h"
#include "Stepper.h"

/*
 * two-wire constructor.
 * Sets which wires should control the motor.
 */
Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2)
{
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;        // the motor speed, in revolutions per minute
  this->direction = 0;      // motor direction
  this->last_step_time = 0;    // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor

  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);

  // When there are only 2 pins, set the other two to 0:
  this->motor_pin_3 = 0;
  this->motor_pin_4 = 0;

  // pin_count is used by the stepMotor() method:
  this->pin_count = 2;
}

/*
 *   constructor for four-pin version
 *   Sets which wires should control the motor.
 */

Stepper::Stepper(int number_of_steps, int motor_pin_1, int motor_pin_2, int motor_pin_3, int motor_pin_4)
{
  this->sleep = 0;    // default to 0 - no sleeping. 1 to sleep. All output drives to zero so no holding torque!
  this->mode = 0;     // full step mode = 0
  this->step_number = 0;      // which step the motor is on
  this->speed = 0;            // the motor speed, in revolutions per minute
  this->direction = 0;        // motor direction
  this->last_step_time = 0;   // time stamp in ms of the last step taken
  this->number_of_steps = number_of_steps;    // total number of steps for this motor

  // Arduino pins for the motor control connection:
  this->motor_pin_1 = motor_pin_1;
  this->motor_pin_2 = motor_pin_2;
  this->motor_pin_3 = motor_pin_3;
  this->motor_pin_4 = motor_pin_4;

  // setup the pins on the microcontroller:
  pinMode(this->motor_pin_1, OUTPUT);
  pinMode(this->motor_pin_2, OUTPUT);
  pinMode(this->motor_pin_3, OUTPUT);
  pinMode(this->motor_pin_4, OUTPUT);

  // pin_count is used by the stepMotor() method:
  this->pin_count = 4;
}

/*
  set to sleep mode for lower power consumption. Only valid in 4 wire mode.
  Remember there's no holding torque!!!
*/

  void Stepper::setSleep(int sleep)
  {
    this->sleep = sleep;

    if (this->sleep == 1) {
      digitalWrite(motor_pin_1, LOW);
      digitalWrite(motor_pin_2, LOW);
      digitalWrite(motor_pin_3, LOW);
      digitalWrite(motor_pin_4, LOW);
    } else {
      stepMotor(this->step_number % 4);
    }
  }

/*
  set stepper mode, full or wave currently. Wave mode for low power applications.
  only applicable in 4 wire setups.
*/

  void Stepper::setMode(int mode)
  {
    this->mode = mode;
  }

/*
  Sets the speed in revs per minute

*/
void Stepper::setSpeed(long whatSpeed)
{
  this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
}

/*
  Moves the motor steps_to_move steps.  If the number is negative,
   the motor moves in the reverse direction.
 */
void Stepper::step(int steps_to_move)
{
  int steps_left = abs(steps_to_move);  // how many steps to take

  // determine direction based on whether steps_to_mode is + or -:
  if (steps_to_move > 0) {this->direction = 1;}
  if (steps_to_move < 0) {this->direction = 0;}

  // decrement the number of steps, moving one step each time:
  while(steps_left > 0) {
  // move only if the appropriate delay has passed:
  if (millis() - this->last_step_time >= this->step_delay) {
      // get the timeStamp of when you stepped:
      this->last_step_time = millis();
      // increment or decrement the step number,
      // depending on direction:
      if (this->direction == 1) {
        this->step_number++;
        if (this->step_number == this->number_of_steps) {
          this->step_number = 0;
        }
      }
      else {
        if (this->step_number == 0) {
          this->step_number = this->number_of_steps;
        }
        this->step_number--;
      }
      // decrement the steps left:
      steps_left--;
      // step the motor to step number 0, 1, 2, or 3:
      stepMotor(this->step_number % 4);
    }
  }
}

/*
 * Moves the motor forward or backwards.
 */
void Stepper::stepMotor(int thisStep)
{
  if (this->pin_count == 2) {
    switch (thisStep) {
      case 0: /* 01 */
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 1: /* 11 */
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, HIGH);
      break;
      case 2: /* 10 */
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
      break;
      case 3: /* 00 */
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, LOW);
      break;
    }
  }
  if (this->pin_count == 4) {
    switch (thisStep) {
      case 0:    // 1010
        digitalWrite(motor_pin_1, HIGH);
        digitalWrite(motor_pin_2, LOW);
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_3, LOW);
        } else {
          digitalWrite(motor_pin_3, HIGH);
        }
        digitalWrite(motor_pin_4, LOW);
      break;
      case 1:    // 0110
        digitalWrite(motor_pin_1, LOW);
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_2, LOW);
        } else {
          digitalWrite(motor_pin_2, HIGH);
        }
        digitalWrite(motor_pin_3, HIGH);
        digitalWrite(motor_pin_4, LOW);
      break;
      case 2:    //0101
        digitalWrite(motor_pin_1, LOW);
        digitalWrite(motor_pin_2, HIGH);
        digitalWrite(motor_pin_3, LOW);
        // mode high for wave step
        if (this->mode) {
            digitalWrite(motor_pin_4, LOW);
        } else {
            digitalWrite(motor_pin_4, HIGH);
        }
      break;
      case 3:    //1001
        // mode high for wave step
        if (this->mode) {
          digitalWrite(motor_pin_1, LOW);
        } else {
          digitalWrite(motor_pin_1, HIGH);
        }
        digitalWrite(motor_pin_2, LOW);
        digitalWrite(motor_pin_3, LOW);
        digitalWrite(motor_pin_4, HIGH);
      break;
    }
  }
}

/*
  version() returns the version of the library:
*/
int Stepper::version(void)
{
  return 7;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwmpmetadata.h"

#include "qwmpevents.h"
#include "qwmpglobal.h"

#include <multimedia/qmediacontent.h>

#include <QtCore/qdatetime.h>
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qsize.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>

struct QWmpMetaDataKeyLookup
{
    QtMedia::MetaData key;
    const wchar_t *token;
};

static const QWmpMetaDataKeyLookup qt_wmpMetaDataKeys[] =
{
    { QtMedia::Title, L"Title" },
    { QtMedia::SubTitle, L"WM/SubTitle" },
    { QtMedia::Author, L"Author" },
    { QtMedia::Comment, L"Comment" },
    { QtMedia::Description, L"Description" },
    { QtMedia::Category, L"WM/Category" },
    { QtMedia::Genre, L"WM/Genre" },
    //{ QtMedia::Date, 0 },
    { QtMedia::Year, L"WM/Year" },
    { QtMedia::UserRating, L"UserRating" },
    //{ QtMedia::MetaDatawords, 0 },
    { QtMedia::Language, L"Language" },
    { QtMedia::Publisher, L"WM/Publisher" },
    { QtMedia::Copyright, L"Copyright" },
    { QtMedia::ParentalRating, L"ParentalRating" },
    { QtMedia::RatingOrganisation, L"RatingOrganisation" },

    // Media
    { QtMedia::Size, L"FileSize" },
    { QtMedia::MediaType, L"MediaType" },
    { QtMedia::Duration, L"Duration" },

    // Audio
    { QtMedia::AudioBitrate, L"AudioBitrate" },
    { QtMedia::AudioCodec, L"AudioCodec" },
    { QtMedia::Channels, L"Channels" },
    { QtMedia::Frequency, L"Frequency" },

    // Music
    { QtMedia::AlbumTitle, L"WM/AlbumTitle" },
    { QtMedia::AlbumArtist, L"WM/AlbumArtist" },
    { QtMedia::ContributingArtist, L"Author" },
    { QtMedia::Composer, L"WM/Composer" },
    { QtMedia::Conductor, L"WM/Conductor" },
    { QtMedia::Lyrics, L"WM/Lyrics" },
    { QtMedia::Mood, L"WM/Mood" },
    { QtMedia::TrackNumber, L"WM/TrackNumber" },
    //{ QtMedia::TrackCount, 0 },
    //{ QtMedia::CoverArtUriSmall, 0 },
    //{ QtMedia::CoverArtUriLarge, 0 },

    // Image/Video
    //{ QtMedia::Resolution, 0 },
    //{ QtMedia::PixelAspectRatio, 0 },

    // Video
    //{ QtMedia::FrameRate, 0 },
    { QtMedia::VideoBitRate, L"VideoBitRate" },
    { QtMedia::VideoCodec, L"VideoCodec" },

    //{ QtMedia::PosterUri, 0 },

    // Movie
    { QtMedia::ChapterNumber, L"ChapterNumber" },
    { QtMedia::Director, L"WM/Director" },
    { QtMedia::LeadPerformer, L"LeadPerformer" },
    { QtMedia::Writer, L"WM/Writer" },

    // Photos
    { QtMedia::CameraManufacturer, L"CameraManufacturer" },
    { QtMedia::CameraModel, L"CameraModel" },
    { QtMedia::Event, L"Event" },
    { QtMedia::Subject, L"Subject" }
};

QWmpMetaData::QWmpMetaData(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
    : QMetaDataControl(parent)
    , m_media(0)
{
    player->get_currentMedia(&m_media);

    connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
            this, SLOT(currentItemChangeEvent(IDispatch*)));
    connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
}

QWmpMetaData::~QWmpMetaData()
{
    if (m_media)
        m_media->Release();
}

bool QWmpMetaData::isMetaDataAvailable() const
{
    return m_media != 0;
}

bool QWmpMetaData::isWritable() const
{
    return m_media != 0;
}

QVariant QWmpMetaData::metaData(QtMedia::MetaData key) const
{
    static const int  count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);

    switch (key) {
    case QtMedia::Date:
        {
            QVariant day = value(m_media, QAutoBStr(L"ReleaseDateDay"));
            QVariant month = value(m_media, QAutoBStr(L"ReleaseDateMonth"));
            QVariant year = value(m_media, QAutoBStr(L"ReleaseDateYear"));

            if (!day.isNull() && !month.isNull() && !year.isNull())
                return QDate(year.toInt(), month.toInt(), day.toInt());
        }
        break;
    case QtMedia::CoverArtUriSmall:
        return albumArtUri(m_media, "_Small.jpg");
    case QtMedia::CoverArtUriLarge:
        return albumArtUri(m_media, "_Large.jpg");
    case QtMedia::Resolution:
        {
            QVariant width = value(m_media, QAutoBStr(L"WM/VideoWidth"));
            QVariant height = value(m_media, QAutoBStr(L"WM/VideoHeight"));

            if (!width.isNull() && !height.isNull())
                return QSize(width.toInt(), height.toInt());
        }
        break;
    case QtMedia::PixelAspectRatio:
        {
            QVariant x = value(m_media, QAutoBStr(L"PixelAspectRatioX"));
            QVariant y = value(m_media, QAutoBStr(L"PixelAspectRatioY"));

            if (!x.isNull() && !y.isNull())
                return QSize(x.toInt(), y.toInt());
        }
        break;
    case QtMedia::FrameRate:
        break;
    default:
        for (int i = 0; i < count; ++i) {
            if (qt_wmpMetaDataKeys[i].key == key)
                return value(m_media, QAutoBStr(qt_wmpMetaDataKeys[i].token));
        }
        break;
    }
    return QVariant();
}

void QWmpMetaData::setMetaData(QtMedia::MetaData key, const QVariant &value)
{
    static const int  count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);

    for (int i = 0; i < count; ++i) {
        if (qt_wmpMetaDataKeys[i].key == key) {
            setValue(m_media, QAutoBStr(qt_wmpMetaDataKeys[i].token), value);
            return;
        }
    }
}

QVariant QWmpMetaData::extendedMetaData(const QString &key) const
{
    return value(m_media, QAutoBStr(key));
}

void QWmpMetaData::setExtendedMetaData(const QString &key, const QVariant &value)
{
    setValue(m_media, QAutoBStr(key), value);
}

void QWmpMetaData::currentItemChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = m_media;

    m_media = 0;
    if (dispatch)
        dispatch->QueryInterface(__uuidof(IWMPMedia), reinterpret_cast<void **>(&m_media));

    if (media) {
        if (m_media)
            emit metaDataChanged();
        else
            emit metaDataAvailableChanged(false);

        media->Release();
    } else {
        if (m_media)
            emit metaDataAvailableChanged(false);
    }
}

void QWmpMetaData::mediaChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch &&  dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        VARIANT_BOOL isEqual = VARIANT_FALSE;
        if (media->get_isIdentical(m_media, &isEqual) == S_OK && isEqual)
            emit metaDataChanged();
        media->Release();
    }
}

QStringList QWmpMetaData::keys(IWMPMedia *media)
{
    QStringList keys;

    long count = 0;
    if (media && media->get_attributeCount(&count) == S_OK) {
        for (long i = 0; i < count; ++i) {
            BSTR string;
            if (media->getAttributeName(i, &string) == S_OK) {
                keys.append(QString::fromWCharArray(string, ::SysStringLen(string)));

                ::SysFreeString(string);
            }
        }
    }
    return keys;
}

QVariant QWmpMetaData::value(IWMPMedia *media, BSTR key)
{
    QVariantList values;
    IWMPMedia3 *media3 = 0;
    if (media && media->QueryInterface(
            __uuidof(IWMPMedia3), reinterpret_cast<void **>(&media3)) == S_OK) {
        long count = 0;
        media3->getAttributeCountByType(key, 0, &count);

        // The count appears to only be valid for static properties, dynamic properties like
        // PlaylistIndex will have a count of zero but return a value for index 0.
        if (count == 0)
            count = 1;

        for (long i = 0; i < count; ++i) {
            VARIANT var;
            VariantInit(&var);

            if (media3->getItemInfoByType(key, 0, i, &var) == S_OK) {
                QVariant value = convertVariant(var);

                if (!value.isNull())
                    values.append(value);

                VariantClear(&var);
            }
        }
        media3->Release();
    }

    switch (values.count()) {
    case 0:
        return QVariant();
    case 1:
        return values.first();
    default:
        return values;
    }
}

void QWmpMetaData::setValue(IWMPMedia *media, BSTR key, const QVariant &value)
{
    if (qVariantCanConvert<QString>(value))
        media->setItemInfo(key, QAutoBStr(value.toString()));
}

QMediaContent QWmpMetaData::resources(IWMPMedia *media)
{
    QMediaContent content;

    BSTR string = 0;
    if (media->get_sourceURL(&string) == S_OK) {
        QString uri = QString::fromWCharArray(static_cast<const wchar_t *>(string));
        ::SysFreeString(string);

        content = QMediaContent(QUrl(uri));

        if (media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
            QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
            ::SysFreeString(string);

            QString albumArtLarge = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Large.jpg");
            QString albumArtSmall = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Small.jpg");

            QDir dir = QFileInfo(uri).absoluteDir();

            if (dir.exists(albumArtLarge))
                content.setCoverArtUriLarge(QUrl(dir.absoluteFilePath(albumArtLarge)));

            if (dir.exists(albumArtSmall))
                content.setCoverArtUriSmall(QUrl(dir.absoluteFilePath(albumArtSmall)));
        }
    }

    return content;
}

QVariant QWmpMetaData::convertVariant(const VARIANT &variant)
{
    switch (variant.vt) {
    case VT_I2:
        return variant.iVal;
    case VT_I4:
        return variant.lVal;
    case VT_I8:
        return variant.llVal;
    case VT_UI2:
        return variant.uiVal;
    case VT_UI4:
        return quint32(variant.ulVal);
    case VT_UI8:
        return variant.ullVal;
    case VT_INT:
        return variant.intVal;
    case VT_UINT:
        return variant.uintVal;
    case VT_BSTR:
        return QString::fromWCharArray(variant.bstrVal, ::SysStringLen(variant.bstrVal));
    case VT_DISPATCH:
        {
            IWMPMetadataPicture *picture = 0;
            IWMPMetadataText *text = 0;

            if (variant.pdispVal->QueryInterface(
                    __uuidof(IWMPMetadataPicture), reinterpret_cast<void **>(&picture)) == S_OK) {
                QUrl uri;
                BSTR string;
                if (picture->get_URL(&string) == S_OK) {
                    uri = QUrl(QString::fromWCharArray(string, ::SysStringLen(string)));

                    ::SysFreeString(string);
                }
                picture->Release();
                return qVariantFromValue(uri);
            } else if (variant.pdispVal->QueryInterface(
                    __uuidof(IWMPMetadataText), reinterpret_cast<void **>(&text)) == S_OK) {
                QString description;
                BSTR string;
                if (text->get_description(&string) == S_OK) {
                    description = QString::fromWCharArray(string, SysStringLen(string));

                    ::SysFreeString(string);
                }
                text->Release();
                return description;
            } else {
                qWarning("Unknown dispatch type");
            }
        }
        break;
    default:
        qWarning("Unsupported Type %d %x", variant.vt, variant.vt);
        break;
    }

    return QVariant();
}

QVariant QWmpMetaData::albumArtUri(IWMPMedia *media, const char *suffix)
{
    BSTR string = 0;
    if (media && media->get_sourceURL(&string) == S_OK) {
        QString uri = QString::fromWCharArray(static_cast<const wchar_t *>(string));
        ::SysFreeString(string);

        if (media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
            QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
            ::SysFreeString(string);

            QString fileName = QLatin1String("AlbumArt_") + uuid + QLatin1String(suffix);

            QDir dir = QFileInfo(uri).absoluteDir();

            if (dir.exists(fileName)) {
                return qVariantFromValue(
                        QUrl(QLatin1String("file:///") + dir.absoluteFilePath(fileName)));
            }
        }
    }
    return QVariant();
}
<commit_msg>wmp; FrameRate -> VideoFrameRate.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwmpmetadata.h"

#include "qwmpevents.h"
#include "qwmpglobal.h"

#include <multimedia/qmediacontent.h>

#include <QtCore/qdatetime.h>
#include <QtCore/qdir.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qsize.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>

struct QWmpMetaDataKeyLookup
{
    QtMedia::MetaData key;
    const wchar_t *token;
};

static const QWmpMetaDataKeyLookup qt_wmpMetaDataKeys[] =
{
    { QtMedia::Title, L"Title" },
    { QtMedia::SubTitle, L"WM/SubTitle" },
    { QtMedia::Author, L"Author" },
    { QtMedia::Comment, L"Comment" },
    { QtMedia::Description, L"Description" },
    { QtMedia::Category, L"WM/Category" },
    { QtMedia::Genre, L"WM/Genre" },
    //{ QtMedia::Date, 0 },
    { QtMedia::Year, L"WM/Year" },
    { QtMedia::UserRating, L"UserRating" },
    //{ QtMedia::MetaDatawords, 0 },
    { QtMedia::Language, L"Language" },
    { QtMedia::Publisher, L"WM/Publisher" },
    { QtMedia::Copyright, L"Copyright" },
    { QtMedia::ParentalRating, L"ParentalRating" },
    { QtMedia::RatingOrganisation, L"RatingOrganisation" },

    // Media
    { QtMedia::Size, L"FileSize" },
    { QtMedia::MediaType, L"MediaType" },
    { QtMedia::Duration, L"Duration" },

    // Audio
    { QtMedia::AudioBitrate, L"AudioBitrate" },
    { QtMedia::AudioCodec, L"AudioCodec" },
    { QtMedia::Channels, L"Channels" },
    { QtMedia::Frequency, L"Frequency" },

    // Music
    { QtMedia::AlbumTitle, L"WM/AlbumTitle" },
    { QtMedia::AlbumArtist, L"WM/AlbumArtist" },
    { QtMedia::ContributingArtist, L"Author" },
    { QtMedia::Composer, L"WM/Composer" },
    { QtMedia::Conductor, L"WM/Conductor" },
    { QtMedia::Lyrics, L"WM/Lyrics" },
    { QtMedia::Mood, L"WM/Mood" },
    { QtMedia::TrackNumber, L"WM/TrackNumber" },
    //{ QtMedia::TrackCount, 0 },
    //{ QtMedia::CoverArtUriSmall, 0 },
    //{ QtMedia::CoverArtUriLarge, 0 },

    // Image/Video
    //{ QtMedia::Resolution, 0 },
    //{ QtMedia::PixelAspectRatio, 0 },

    // Video
    //{ QtMedia::FrameRate, 0 },
    { QtMedia::VideoBitRate, L"VideoBitRate" },
    { QtMedia::VideoCodec, L"VideoCodec" },

    //{ QtMedia::PosterUri, 0 },

    // Movie
    { QtMedia::ChapterNumber, L"ChapterNumber" },
    { QtMedia::Director, L"WM/Director" },
    { QtMedia::LeadPerformer, L"LeadPerformer" },
    { QtMedia::Writer, L"WM/Writer" },

    // Photos
    { QtMedia::CameraManufacturer, L"CameraManufacturer" },
    { QtMedia::CameraModel, L"CameraModel" },
    { QtMedia::Event, L"Event" },
    { QtMedia::Subject, L"Subject" }
};

QWmpMetaData::QWmpMetaData(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
    : QMetaDataControl(parent)
    , m_media(0)
{
    player->get_currentMedia(&m_media);

    connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
            this, SLOT(currentItemChangeEvent(IDispatch*)));
    connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
}

QWmpMetaData::~QWmpMetaData()
{
    if (m_media)
        m_media->Release();
}

bool QWmpMetaData::isMetaDataAvailable() const
{
    return m_media != 0;
}

bool QWmpMetaData::isWritable() const
{
    return m_media != 0;
}

QVariant QWmpMetaData::metaData(QtMedia::MetaData key) const
{
    static const int  count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);

    switch (key) {
    case QtMedia::Date:
        {
            QVariant day = value(m_media, QAutoBStr(L"ReleaseDateDay"));
            QVariant month = value(m_media, QAutoBStr(L"ReleaseDateMonth"));
            QVariant year = value(m_media, QAutoBStr(L"ReleaseDateYear"));

            if (!day.isNull() && !month.isNull() && !year.isNull())
                return QDate(year.toInt(), month.toInt(), day.toInt());
        }
        break;
    case QtMedia::CoverArtUriSmall:
        return albumArtUri(m_media, "_Small.jpg");
    case QtMedia::CoverArtUriLarge:
        return albumArtUri(m_media, "_Large.jpg");
    case QtMedia::Resolution:
        {
            QVariant width = value(m_media, QAutoBStr(L"WM/VideoWidth"));
            QVariant height = value(m_media, QAutoBStr(L"WM/VideoHeight"));

            if (!width.isNull() && !height.isNull())
                return QSize(width.toInt(), height.toInt());
        }
        break;
    case QtMedia::PixelAspectRatio:
        {
            QVariant x = value(m_media, QAutoBStr(L"PixelAspectRatioX"));
            QVariant y = value(m_media, QAutoBStr(L"PixelAspectRatioY"));

            if (!x.isNull() && !y.isNull())
                return QSize(x.toInt(), y.toInt());
        }
        break;
    case QtMedia::VideoFrameRate:
        break;
    default:
        for (int i = 0; i < count; ++i) {
            if (qt_wmpMetaDataKeys[i].key == key)
                return value(m_media, QAutoBStr(qt_wmpMetaDataKeys[i].token));
        }
        break;
    }
    return QVariant();
}

void QWmpMetaData::setMetaData(QtMedia::MetaData key, const QVariant &value)
{
    static const int  count = sizeof(qt_wmpMetaDataKeys) / sizeof(QWmpMetaDataKeyLookup);

    for (int i = 0; i < count; ++i) {
        if (qt_wmpMetaDataKeys[i].key == key) {
            setValue(m_media, QAutoBStr(qt_wmpMetaDataKeys[i].token), value);
            return;
        }
    }
}

QVariant QWmpMetaData::extendedMetaData(const QString &key) const
{
    return value(m_media, QAutoBStr(key));
}

void QWmpMetaData::setExtendedMetaData(const QString &key, const QVariant &value)
{
    setValue(m_media, QAutoBStr(key), value);
}

void QWmpMetaData::currentItemChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = m_media;

    m_media = 0;
    if (dispatch)
        dispatch->QueryInterface(__uuidof(IWMPMedia), reinterpret_cast<void **>(&m_media));

    if (media) {
        if (m_media)
            emit metaDataChanged();
        else
            emit metaDataAvailableChanged(false);

        media->Release();
    } else {
        if (m_media)
            emit metaDataAvailableChanged(false);
    }
}

void QWmpMetaData::mediaChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch &&  dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        VARIANT_BOOL isEqual = VARIANT_FALSE;
        if (media->get_isIdentical(m_media, &isEqual) == S_OK && isEqual)
            emit metaDataChanged();
        media->Release();
    }
}

QStringList QWmpMetaData::keys(IWMPMedia *media)
{
    QStringList keys;

    long count = 0;
    if (media && media->get_attributeCount(&count) == S_OK) {
        for (long i = 0; i < count; ++i) {
            BSTR string;
            if (media->getAttributeName(i, &string) == S_OK) {
                keys.append(QString::fromWCharArray(string, ::SysStringLen(string)));

                ::SysFreeString(string);
            }
        }
    }
    return keys;
}

QVariant QWmpMetaData::value(IWMPMedia *media, BSTR key)
{
    QVariantList values;
    IWMPMedia3 *media3 = 0;
    if (media && media->QueryInterface(
            __uuidof(IWMPMedia3), reinterpret_cast<void **>(&media3)) == S_OK) {
        long count = 0;
        media3->getAttributeCountByType(key, 0, &count);

        // The count appears to only be valid for static properties, dynamic properties like
        // PlaylistIndex will have a count of zero but return a value for index 0.
        if (count == 0)
            count = 1;

        for (long i = 0; i < count; ++i) {
            VARIANT var;
            VariantInit(&var);

            if (media3->getItemInfoByType(key, 0, i, &var) == S_OK) {
                QVariant value = convertVariant(var);

                if (!value.isNull())
                    values.append(value);

                VariantClear(&var);
            }
        }
        media3->Release();
    }

    switch (values.count()) {
    case 0:
        return QVariant();
    case 1:
        return values.first();
    default:
        return values;
    }
}

void QWmpMetaData::setValue(IWMPMedia *media, BSTR key, const QVariant &value)
{
    if (qVariantCanConvert<QString>(value))
        media->setItemInfo(key, QAutoBStr(value.toString()));
}

QMediaContent QWmpMetaData::resources(IWMPMedia *media)
{
    QMediaContent content;

    BSTR string = 0;
    if (media->get_sourceURL(&string) == S_OK) {
        QString uri = QString::fromWCharArray(static_cast<const wchar_t *>(string));
        ::SysFreeString(string);

        content = QMediaContent(QUrl(uri));

        if (media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
            QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
            ::SysFreeString(string);

            QString albumArtLarge = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Large.jpg");
            QString albumArtSmall = QLatin1String("AlbumArt_") + uuid + QLatin1String("_Small.jpg");

            QDir dir = QFileInfo(uri).absoluteDir();

            if (dir.exists(albumArtLarge))
                content.setCoverArtUriLarge(QUrl(dir.absoluteFilePath(albumArtLarge)));

            if (dir.exists(albumArtSmall))
                content.setCoverArtUriSmall(QUrl(dir.absoluteFilePath(albumArtSmall)));
        }
    }

    return content;
}

QVariant QWmpMetaData::convertVariant(const VARIANT &variant)
{
    switch (variant.vt) {
    case VT_I2:
        return variant.iVal;
    case VT_I4:
        return variant.lVal;
    case VT_I8:
        return variant.llVal;
    case VT_UI2:
        return variant.uiVal;
    case VT_UI4:
        return quint32(variant.ulVal);
    case VT_UI8:
        return variant.ullVal;
    case VT_INT:
        return variant.intVal;
    case VT_UINT:
        return variant.uintVal;
    case VT_BSTR:
        return QString::fromWCharArray(variant.bstrVal, ::SysStringLen(variant.bstrVal));
    case VT_DISPATCH:
        {
            IWMPMetadataPicture *picture = 0;
            IWMPMetadataText *text = 0;

            if (variant.pdispVal->QueryInterface(
                    __uuidof(IWMPMetadataPicture), reinterpret_cast<void **>(&picture)) == S_OK) {
                QUrl uri;
                BSTR string;
                if (picture->get_URL(&string) == S_OK) {
                    uri = QUrl(QString::fromWCharArray(string, ::SysStringLen(string)));

                    ::SysFreeString(string);
                }
                picture->Release();
                return qVariantFromValue(uri);
            } else if (variant.pdispVal->QueryInterface(
                    __uuidof(IWMPMetadataText), reinterpret_cast<void **>(&text)) == S_OK) {
                QString description;
                BSTR string;
                if (text->get_description(&string) == S_OK) {
                    description = QString::fromWCharArray(string, SysStringLen(string));

                    ::SysFreeString(string);
                }
                text->Release();
                return description;
            } else {
                qWarning("Unknown dispatch type");
            }
        }
        break;
    default:
        qWarning("Unsupported Type %d %x", variant.vt, variant.vt);
        break;
    }

    return QVariant();
}

QVariant QWmpMetaData::albumArtUri(IWMPMedia *media, const char *suffix)
{
    BSTR string = 0;
    if (media && media->get_sourceURL(&string) == S_OK) {
        QString uri = QString::fromWCharArray(static_cast<const wchar_t *>(string));
        ::SysFreeString(string);

        if (media->getItemInfo(QAutoBStr(L"WM/WMCollectionGroupID"), &string) == S_OK) {
            QString uuid = QString::fromWCharArray(static_cast<const wchar_t *>(string));
            ::SysFreeString(string);

            QString fileName = QLatin1String("AlbumArt_") + uuid + QLatin1String(suffix);

            QDir dir = QFileInfo(uri).absoluteDir();

            if (dir.exists(fileName)) {
                return qVariantFromValue(
                        QUrl(QLatin1String("file:///") + dir.absoluteFilePath(fileName)));
            }
        }
    }
    return QVariant();
}
<|endoftext|>


<commit_before>// ------------------------------------------------------------------------
// audioio-jack.cpp: Interface to JACK audio framework
// Copyright (C) 2001,2002 Kai Vehmanen (kai.vehmanen@wakkanet.fi)
// 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 2 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <iostream>

#include <jack/jack.h>
#include <kvu_dbc.h>
#include <kvu_numtostr.h>

#include "audioio.h"
#include "eca-version.h"
#include "eca-logger.h"

#include "audioio_jack.h"
#include "audioio_jack_manager.h"

#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
/* see eca-static-object-maps.cpp */
static const char* audio_io_keyword_const = "jack";
static const char* audio_io_keyword_regex_const = "(^jack$)|(^jack_alsa$)|(^jack_auto$)|(^jack_generic$)";

AUDIO_IO* audio_io_descriptor(void) { return(new AUDIO_IO_JACK()); }
const char* audio_io_keyword(void){return(audio_io_keyword_const); }
const char* audio_io_keyword_regex(void){return(audio_io_keyword_regex_const); }
int audio_io_interface_version(void) { return(ecasound_library_version_current); }
#endif

AUDIO_IO_JACK::AUDIO_IO_JACK (void)
{
  ECA_LOG_MSG(ECA_LOGGER::functions, "(audioio-jack) constructor");

  jackmgr_rep = 0;
  myid_rep = 0;
  secondparam_rep = "";
}

AUDIO_IO_JACK::~AUDIO_IO_JACK(void)
{
  if (is_open() == true && is_running()) stop();
  if (is_open() == true) {
    close();
  }
}

AUDIO_IO_MANAGER* AUDIO_IO_JACK::create_object_manager(void) const
{
  return(new AUDIO_IO_JACK_MANAGER());
}

void AUDIO_IO_JACK::set_manager(AUDIO_IO_JACK_MANAGER* mgr, int id)
{
  string mgrname = (mgr == 0 ? mgr->name() : "null");
  ECA_LOG_MSG(ECA_LOGGER::system_objects,
		"(audioio-jack) setting manager to " + mgr->name());
  jackmgr_rep = mgr;
  myid_rep = id;
}

void AUDIO_IO_JACK::open(void) throw(AUDIO_IO::SETUP_ERROR&)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) open");

  set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32_le);
  toggle_interleaved_channels(false);

  if (jackmgr_rep != 0) {
    string my_in_portname ("in"), my_out_portname ("out");

    if (label() == "jack_generic") {
      my_in_portname = my_out_portname = secondparam_rep;
    }

    // FIXME: required?
    // if (workstring.size() == 0) workstring = label();

    jackmgr_rep->open(myid_rep);

    if (jackmgr_rep->is_open() != true) {
      /* unable to open connection to jackd, exit */
      throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-JACK: Unable to open JACK-client"));
    }

    if (samples_per_second() != jackmgr_rep->samples_per_second()) {
      jackmgr_rep->close(myid_rep);
      throw(SETUP_ERROR(SETUP_ERROR::unexpected,
			"AUDIOIO-JACK: Cannot connect open connection! Samplerate " +
			kvu_numtostr(samples_per_second()) + " differs from JACK server's buffersize of " +
			kvu_numtostr(jackmgr_rep->samples_per_second()) + "."));
    }

    if (buffersize() != jackmgr_rep->buffersize()) {
      long int jackd_bsize = jackmgr_rep->buffersize();
      jackmgr_rep->close(myid_rep);
      throw(SETUP_ERROR(SETUP_ERROR::unexpected,
			"AUDIOIO-JACK: Cannot connect open connection! Buffersize " +
			kvu_numtostr(buffersize()) + " differs from JACK server's buffersize of " +
			kvu_numtostr(jackd_bsize) + "."));
    }

    if (io_mode() == AUDIO_IO::io_read) {
      jackmgr_rep->register_jack_ports(myid_rep, channels(), my_in_portname);
    }
    else {
      jackmgr_rep->register_jack_ports(myid_rep, channels(), my_out_portname);
    }

    if (label() != "jack_generic" && label() != "jack") {
      string in_aconn_portprefix, out_aconn_portprefix;

      if (label() == "jack_alsa") {
	in_aconn_portprefix = "alsa_pcm:capture_";
	out_aconn_portprefix = "alsa_pcm:playback_";
      }
      else if (label() == "jack_auto") {
	in_aconn_portprefix = secondparam_rep + ":out_";
	out_aconn_portprefix = secondparam_rep + ":in_";
      }

      for(int n = 0; n < channels(); n++) {
	if (io_mode() == AUDIO_IO::io_read) {
	  jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, in_aconn_portprefix + kvu_numtostr(n + 1));
	}
	else {
	  jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, out_aconn_portprefix + kvu_numtostr(n + 1));
	}
      }
    }
  }

  AUDIO_IO_DEVICE::open();
}

void AUDIO_IO_JACK::close(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) close");

  if (jackmgr_rep != 0) {
    jackmgr_rep->unregister_jack_ports(myid_rep);
    jackmgr_rep->close(myid_rep);
  }

  AUDIO_IO_DEVICE::close();
}

bool AUDIO_IO_JACK::finished(void) const
{
  if (is_open() != true ||
      jackmgr_rep == 0 ||
      jackmgr_rep->is_open() != true)
    return(true);

  return(false);
}

long int AUDIO_IO_JACK::read_samples(void* target_buffer, long int samples)
{
  if (jackmgr_rep != 0) {
    long int res = jackmgr_rep->read_samples(myid_rep, target_buffer, samples);
    return(res);
  }

  return(0);
}

void AUDIO_IO_JACK::write_samples(void* target_buffer, long int samples)
{
  if (jackmgr_rep != 0) {
    jackmgr_rep->write_samples(myid_rep, target_buffer, samples);
  }
}

void AUDIO_IO_JACK::prepare(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) prepare / " + label());
  AUDIO_IO_DEVICE::prepare();
}

void AUDIO_IO_JACK::start(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) start / " + label());
  AUDIO_IO_DEVICE::start();
}

void AUDIO_IO_JACK::stop(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) stop / " + label());
  AUDIO_IO_DEVICE::stop();
}

long int AUDIO_IO_JACK::latency(void) const
{
  return(jackmgr_rep == 0 ? 0 : jackmgr_rep->client_latency(myid_rep));
}

std::string AUDIO_IO_JACK::parameter_names(void) const
{
  if (label() == "jack_generic")
    return("label,portname");

  if (label() == "jack_auto")
    return("label,client");

  /* jack, jack_alsa */
  return("label");
}

void AUDIO_IO_JACK::set_parameter(int param, std::string value)
{
  switch(param)
    {
    case 1: { set_label(value); break; }
    case 2: { secondparam_rep = value; break; }
    }
}

std::string AUDIO_IO_JACK::get_parameter(int param) const
{
  switch(param)
    {
    case 1: { return(label()); }
    case 2: { return(secondparam_rep); }
    }

  return("");
}
<commit_msg>Typo in the error message.<commit_after>// ------------------------------------------------------------------------
// audioio-jack.cpp: Interface to JACK audio framework
// Copyright (C) 2001,2002 Kai Vehmanen (kai.vehmanen@wakkanet.fi)
// 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 2 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, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
// ------------------------------------------------------------------------

#include <iostream>

#include <jack/jack.h>
#include <kvu_dbc.h>
#include <kvu_numtostr.h>

#include "audioio.h"
#include "eca-version.h"
#include "eca-logger.h"

#include "audioio_jack.h"
#include "audioio_jack_manager.h"

#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
/* see eca-static-object-maps.cpp */
static const char* audio_io_keyword_const = "jack";
static const char* audio_io_keyword_regex_const = "(^jack$)|(^jack_alsa$)|(^jack_auto$)|(^jack_generic$)";

AUDIO_IO* audio_io_descriptor(void) { return(new AUDIO_IO_JACK()); }
const char* audio_io_keyword(void){return(audio_io_keyword_const); }
const char* audio_io_keyword_regex(void){return(audio_io_keyword_regex_const); }
int audio_io_interface_version(void) { return(ecasound_library_version_current); }
#endif

AUDIO_IO_JACK::AUDIO_IO_JACK (void)
{
  ECA_LOG_MSG(ECA_LOGGER::functions, "(audioio-jack) constructor");

  jackmgr_rep = 0;
  myid_rep = 0;
  secondparam_rep = "";
}

AUDIO_IO_JACK::~AUDIO_IO_JACK(void)
{
  if (is_open() == true && is_running()) stop();
  if (is_open() == true) {
    close();
  }
}

AUDIO_IO_MANAGER* AUDIO_IO_JACK::create_object_manager(void) const
{
  return(new AUDIO_IO_JACK_MANAGER());
}

void AUDIO_IO_JACK::set_manager(AUDIO_IO_JACK_MANAGER* mgr, int id)
{
  string mgrname = (mgr == 0 ? mgr->name() : "null");
  ECA_LOG_MSG(ECA_LOGGER::system_objects,
		"(audioio-jack) setting manager to " + mgr->name());
  jackmgr_rep = mgr;
  myid_rep = id;
}

void AUDIO_IO_JACK::open(void) throw(AUDIO_IO::SETUP_ERROR&)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) open");

  set_sample_format(ECA_AUDIO_FORMAT::sfmt_f32_le);
  toggle_interleaved_channels(false);

  if (jackmgr_rep != 0) {
    string my_in_portname ("in"), my_out_portname ("out");

    if (label() == "jack_generic") {
      my_in_portname = my_out_portname = secondparam_rep;
    }

    // FIXME: required?
    // if (workstring.size() == 0) workstring = label();

    jackmgr_rep->open(myid_rep);

    if (jackmgr_rep->is_open() != true) {
      /* unable to open connection to jackd, exit */
      throw(SETUP_ERROR(SETUP_ERROR::unexpected, "AUDIOIO-JACK: Unable to open JACK-client"));
    }

    if (samples_per_second() != jackmgr_rep->samples_per_second()) {
      jackmgr_rep->close(myid_rep);
      throw(SETUP_ERROR(SETUP_ERROR::unexpected,
			"AUDIOIO-JACK: Cannot connect open connection! Samplerate " +
			kvu_numtostr(samples_per_second()) + " differs from JACK server's sample rate of " +
			kvu_numtostr(jackmgr_rep->samples_per_second()) + "."));
    }

    if (buffersize() != jackmgr_rep->buffersize()) {
      long int jackd_bsize = jackmgr_rep->buffersize();
      jackmgr_rep->close(myid_rep);
      throw(SETUP_ERROR(SETUP_ERROR::unexpected,
			"AUDIOIO-JACK: Cannot connect open connection! Buffersize " +
			kvu_numtostr(buffersize()) + " differs from JACK server's buffersize of " +
			kvu_numtostr(jackd_bsize) + "."));
    }

    if (io_mode() == AUDIO_IO::io_read) {
      jackmgr_rep->register_jack_ports(myid_rep, channels(), my_in_portname);
    }
    else {
      jackmgr_rep->register_jack_ports(myid_rep, channels(), my_out_portname);
    }

    if (label() != "jack_generic" && label() != "jack") {
      string in_aconn_portprefix, out_aconn_portprefix;

      if (label() == "jack_alsa") {
	in_aconn_portprefix = "alsa_pcm:capture_";
	out_aconn_portprefix = "alsa_pcm:playback_";
      }
      else if (label() == "jack_auto") {
	in_aconn_portprefix = secondparam_rep + ":out_";
	out_aconn_portprefix = secondparam_rep + ":in_";
      }

      for(int n = 0; n < channels(); n++) {
	if (io_mode() == AUDIO_IO::io_read) {
	  jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, in_aconn_portprefix + kvu_numtostr(n + 1));
	}
	else {
	  jackmgr_rep->auto_connect_jack_port(myid_rep, n + 1, out_aconn_portprefix + kvu_numtostr(n + 1));
	}
      }
    }
  }

  AUDIO_IO_DEVICE::open();
}

void AUDIO_IO_JACK::close(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) close");

  if (jackmgr_rep != 0) {
    jackmgr_rep->unregister_jack_ports(myid_rep);
    jackmgr_rep->close(myid_rep);
  }

  AUDIO_IO_DEVICE::close();
}

bool AUDIO_IO_JACK::finished(void) const
{
  if (is_open() != true ||
      jackmgr_rep == 0 ||
      jackmgr_rep->is_open() != true)
    return(true);

  return(false);
}

long int AUDIO_IO_JACK::read_samples(void* target_buffer, long int samples)
{
  if (jackmgr_rep != 0) {
    long int res = jackmgr_rep->read_samples(myid_rep, target_buffer, samples);
    return(res);
  }

  return(0);
}

void AUDIO_IO_JACK::write_samples(void* target_buffer, long int samples)
{
  if (jackmgr_rep != 0) {
    jackmgr_rep->write_samples(myid_rep, target_buffer, samples);
  }
}

void AUDIO_IO_JACK::prepare(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) prepare / " + label());
  AUDIO_IO_DEVICE::prepare();
}

void AUDIO_IO_JACK::start(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) start / " + label());
  AUDIO_IO_DEVICE::start();
}

void AUDIO_IO_JACK::stop(void)
{
  ECA_LOG_MSG(ECA_LOGGER::system_objects, "(audioio-jack) stop / " + label());
  AUDIO_IO_DEVICE::stop();
}

long int AUDIO_IO_JACK::latency(void) const
{
  return(jackmgr_rep == 0 ? 0 : jackmgr_rep->client_latency(myid_rep));
}

std::string AUDIO_IO_JACK::parameter_names(void) const
{
  if (label() == "jack_generic")
    return("label,portname");

  if (label() == "jack_auto")
    return("label,client");

  /* jack, jack_alsa */
  return("label");
}

void AUDIO_IO_JACK::set_parameter(int param, std::string value)
{
  switch(param)
    {
    case 1: { set_label(value); break; }
    case 2: { secondparam_rep = value; break; }
    }
}

std::string AUDIO_IO_JACK::get_parameter(int param) const
{
  switch(param)
    {
    case 1: { return(label()); }
    case 2: { return(secondparam_rep); }
    }

  return("");
}
<|endoftext|>


<commit_before>#include <raytracer.h>
#include <bodies.h>

#include <cmath>
#include <cassert>

using namespace raytracer;

Cylinder::Cylinder() {
	setSize(1.0);
	setOrientation(Vector(0.0,1.0,0.0));
	setPosition(Vector(0.0,0.0,0.0));
}

Cylinder::Cylinder(const Vector & p, const Vector & v, double radius) {
	setSize(radius);
	setOrientation(v);
	setPosition(p);
}

Body * Cylinder::clone() const {
	return (Body*) new Cylinder(*this);
}

void Cylinder::setSize(double radius) {
	assert(radius > DIV_LIMIT);

	size = radius;
	magnitude = radius * radius;
	reciprocal = 1 / radius;
}

//Cylinder uses the z_axis orientation vector from BasicBody as its axis
void Cylinder::setOrientation(const Vector & v) {
	x_axis.copy(1.0,0.0,0.0);
	y_axis.copy(0.0,1.0,0.0);
	z_axis.copy(v);
}

double Cylinder::getDistance(const Ray  & r) const {
	//magnitude is radius squared
	//position and direction are vectors defining position/orientation
	Vector v = r.p, w = r.v;
	v.subtract(position);
	v.cross(z_axis);
	w.cross(z_axis);
	double vv = v.dot(), vw = v.dot(w), ww = w.dot();
	double radical = vw*vw + ww / magnitude - vv*ww;

	if (radical < DIV_LIMIT) return -1.0;
	else radical = std::sqrt(radical) / ww;

	double distance = -vw / ww - radical;
	if (distance < DIV_LIMIT) {
		distance = -vw / ww + radical;
		if (distance < DIV_LIMIT) {
			return -1.0;
		}
		else return distance;
	}

	else return distance;
}

Vector Cylinder::getNormal(const Vector & p) const {
	Vector result = p, projection = z_axis;
	projection.dot(p);
	result.subtract(projection);
	result.scale(reciprocal);
	return result;
}
<commit_msg>using new api<commit_after>#include <raytracer.h>
#include <bodies.h>

#include <cmath>
#include <cassert>

using namespace raytracer;

Cylinder::Cylinder() {
	useDefaults();
}

Body * Cylinder::clone() const {
	return (Body*) new Cylinder(*this);
}

double Cylinder::getDistance(const Ray  & r) const {
	//magnitude is radius squared
	//position and direction are vectors defining position/orientation
	Vector v = r.p, w = r.v;
	v.subtract(position);
	v.cross(orientation);
	w.cross(orientation);
	double vv = v.dot(), vw = v.dot(w), ww = w.dot();
	double radical = vw*vw + ww / magnitude - vv*ww;

	if (radical < ZERO) return -1.0;
	else radical = std::sqrt(radical) / ww;

	double distance = -vw / ww - radical;
	if (distance < ZERO) {
		distance = -vw / ww + radical;
		if (distance < ZERO) {
			return -1.0;
		}
		else return distance;
	}

	else return distance;
}

Vector Cylinder::getNormal(const Vector & p) const {
	Vector result = p, projection = orientation;
	projection.dot(p);
	result.subtract(projection);
	result.scale(reciprocal);

	if (matte) {
		result.add(Vector::random(normal_delta);
		result.normalize();
	}

	assert(std::abs(result.dot() - 1.0) < ZERO);

	return result;
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

#if !defined(__CINT__) || defined(__MAKECINT__)

/// This macro runs the test preprocessor for MUON.
/// It uses AliTestShuttle to simulate a full Shuttle process
///
/// The input data has to be created first by other processes (or is created
/// here by CreateDCSAliasMap() for tracker HV).
///
/// To play with it, you'll have to set/modify several lines, to
/// a) select input files, using shuttle->AddInputFile()
/// b) select run type, using shuttle->AddInputRunParameter() (the run type
///    dictates which task is really performed by the MUONPreprocessor
///
/// You must load relevant libraries (besides normal MUON ones) before
/// compiling this macro :
///
/// gSystem->Load("$ALICE_ROOT/SHUTTLE/TestShuttle/libTestShuttle");
/// gSystem->Load("libMUONshuttle.so");
///
///
/// For more information on usage, please see READMEshuttle.
///
// By Laurent Aphecetche, SUBATECH Nantes

#include "TestMUONPreprocessor.h"

#include "AliMUONTrackerPreprocessor.h"
#include "AliMUONTriggerPreprocessor.h"

#include "AliLog.h"

#include "AliMpExMap.h"
#include "AliMpHelper.h"
#include "AliMpHVNamer.h"
#include "AliMpCDB.h"

#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBId.h"
#include "AliShuttleInterface.h"
#include "AliTestShuttle.h"
#include "AliDCSValue.h"

#include "Riostream.h"
#include "TSystem.h"
#include "TMap.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TString.h"
#include "TRandom.h"
#endif

void TestMUONPreprocessor(Int_t runNumber=80, const char* runType="PEDESTAL_RUN")
{
  // runType can be :
  //
  // PEDESTAL_RUN -> pedestals
  // ELECTRONICS_CALIBRATION_RUN -> gains
  // PHYSICS -> HV
  // GMS

  // create AliTestShuttle instance
  // The parameters are run, startTime, endTime
  AliTestShuttle* shuttle = new AliTestShuttle(runNumber, 0, 1);

  const char* inputCDB = "local://$ALICE_ROOT/SHUTTLE/TestShuttle/TestCDB";

  AliTestShuttle::SetMainCDB(inputCDB);
  AliTestShuttle::SetMainRefStorage("local://$ALICE_ROOT/SHUTTLE/TestShuttle/TestReference");

  // Create DCS HV aliases
  TMap* dcsAliasMap = CreateDCSAliasMap(inputCDB);

  if ( dcsAliasMap )
  {
    // now give the alias map to the shuttle
    shuttle->SetDCSInput(dcsAliasMap);
  }

  printf("Test Shuttle temp dir: %s\n", AliShuttleInterface::GetShuttleTempDir());
  printf("Test Shuttle log dir: %s\n", AliShuttleInterface::GetShuttleLogDir());
  printf("Test OCDB storage Uri: %s\n", AliShuttleInterface::GetMainCDB().Data());
  printf("Test Reference storage Uri: %s\n", AliShuttleInterface::GetMainRefStorage().Data());

  // The shuttle can process files that originate from DCS, DAQ and HLT.
  // To test it, we provide some local files and locations where these would be found when
  // the online machinery would be there.
  // In real life this functions would be produces by the sub-detectors
  // calibration programs in DCS, DAQ or HLT. These files can then be retrieved using the Shuttle.
  //
  // Files are added with the function AliTestShuttle::AddInputFile. The syntax is:
  // AddInputFile(<system>, <detector>, <id>, <source>, <local-file>)
  // In this example we add 4 files originating from different LDCs but with the same id (PEDESTALS)

  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC0","$ALICE_ROOT/MUON/data/LDC0.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC1","$ALICE_ROOT/MUON/data/LDC1.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC2","$ALICE_ROOT/MUON/data/LDC2.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC3","$ALICE_ROOT/MUON/data/LDC3.ped");

  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC0","$ALICE_ROOT/MUON/data/LDC0.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC1","$ALICE_ROOT/MUON/data/LDC1.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC2","$ALICE_ROOT/MUON/data/LDC2.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC3","$ALICE_ROOT/MUON/data/LDC3.gain");

  // and GMS file
  shuttle->AddInputFile(AliTestShuttle::kDCS,"MCH","GMS","GMS","$ALICE_ROOT/MUON/data/GMS.root");

  // and then the trigger stuff
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","LOCAL","LDC0","$ALICE_ROOT/MUON/data/MtgLocalMask-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","REGIONAL","LDC0","$ALICE_ROOT/MUON/data/MtgRegionalCrate-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","GLOBAL","LDC0","$ALICE_ROOT/MUON/data/MtgGlobalCrate-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","LUT","LDC0","$ALICE_ROOT/MUON/data/MtgLocalLut-1.dat");

  // The shuttle can read run parameters stored in the DAQ run logbook.
  // To test it, we must provide the run parameters manually. They will be retrieved in the preprocessor
  // using GetRunParameter function.
  // In real life the parameters will be retrieved automatically from the run logbook;
  shuttle->SetInputRunType(runType);

  // Create the preprocessor that should be tested, it registers itself automatically to the shuttle
  new AliMUONTrackerPreprocessor(shuttle);
  new AliMUONTriggerPreprocessor(shuttle);

  shuttle->Print();

  // Test the preprocessor
  shuttle->Process();
}

TMap* CreateDCSAliasMap(const char* inputCDB)
{
  /// Creates a DCS structure for MUON Tracker HV
  ///
  /// The structure is the following:
  ///   TMap (key --> value)
  ///     <DCSAlias> --> <valueList>
  ///     <DCSAlias> is a string
  ///     <valueList> is a TObjArray of AliDCSValue
  ///     An AliDCSValue consists of timestamp and a value in form of a AliSimpleValue

  Bool_t undefStorage(kFALSE);

  AliCDBManager* man = AliCDBManager::Instance();
  if (!man->IsDefaultStorageSet())
  {
    undefStorage = kTRUE;
    man->SetDefaultStorage(inputCDB);
  }

  // Load mapping
  Bool_t ok = AliMpCDB::LoadDDLStore();

  if (undefStorage)
  {
    man->UnsetDefaultStorage();
  }

  if (!ok)
  {
    AliErrorGeneral("CreateDCSAliasMap","Could not load DDLStore from OCDB");
    return 0x0;
  }

  TMap* aliasMap = new TMap;
  aliasMap->SetOwner(kTRUE);

  TRandom random(0);

  AliMpHVNamer hvNamer;

  TObjArray* aliases = hvNamer.GenerateAliases();

  for ( Int_t i = 0; i < aliases->GetEntries(); ++i )
  {
    TObjString* alias = static_cast<TObjString*>(aliases->At(i));
    TString& aliasName = alias->String();
    if ( aliasName.Contains("sw") )
    {
      // HV Switch (St345 only)
      TObjArray* valueSet = new TObjArray;
      valueSet->SetOwner(kTRUE);
      Bool_t value = kTRUE;
//      Float_t r = random.Uniform();
//      if ( r < 0.007 ) value = kFALSE;
//      if ( aliasName.Contains("DE513sw2") ) value = kFALSE;

      for ( UInt_t timeStamp = 0; timeStamp < 60*3; timeStamp += 60 )
      {
        AliDCSValue* dcsValue = new AliDCSValue(value,timeStamp);
        valueSet->Add(dcsValue);
      }
      aliasMap->Add(new TObjString(*alias),valueSet);
    }
    else
    {
      TObjArray* valueSet = new TObjArray;
      valueSet->SetOwner(kTRUE);
      for ( UInt_t timeStamp = 0; timeStamp < 60*15; timeStamp += 120 )
      {
        Float_t value = random.Gaus(1750,62.5);
        if ( aliasName == "MchHvLvLeft/Chamber00Left/Quad2Sect1.actual.vMon") value = 500;
        AliDCSValue* dcsValue = new AliDCSValue(value,timeStamp);
        valueSet->Add(dcsValue);
      }
      if ( aliasName == "MchHvLvLeft/Chamber04Left/Slat06.actual.vMon" ) continue;
      aliasMap->Add(new TObjString(*alias),valueSet);
    }
  }

  delete aliases;

  return aliasMap;
}

<commit_msg>Adding MtgCurrent.dat input file for trigger (Laurent)<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

#if !defined(__CINT__) || defined(__MAKECINT__)

/// This macro runs the test preprocessor for MUON.
/// It uses AliTestShuttle to simulate a full Shuttle process
///
/// The input data has to be created first by other processes (or is created
/// here by CreateDCSAliasMap() for tracker HV).
///
/// To play with it, you'll have to set/modify several lines, to
/// a) select input files, using shuttle->AddInputFile()
/// b) select run type, using shuttle->AddInputRunParameter() (the run type
///    dictates which task is really performed by the MUONPreprocessor
///
/// You must load relevant libraries (besides normal MUON ones) before
/// compiling this macro :
///
/// gSystem->Load("$ALICE_ROOT/SHUTTLE/TestShuttle/libTestShuttle");
/// gSystem->Load("libMUONshuttle.so");
///
///
/// For more information on usage, please see READMEshuttle.
///
// By Laurent Aphecetche, SUBATECH Nantes

#include "TestMUONPreprocessor.h"

#include "AliMUONTrackerPreprocessor.h"
#include "AliMUONTriggerPreprocessor.h"

#include "AliLog.h"

#include "AliMpExMap.h"
#include "AliMpHelper.h"
#include "AliMpHVNamer.h"
#include "AliMpCDB.h"

#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliCDBId.h"
#include "AliShuttleInterface.h"
#include "AliTestShuttle.h"
#include "AliDCSValue.h"

#include "Riostream.h"
#include "TSystem.h"
#include "TMap.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TString.h"
#include "TRandom.h"
#endif

void TestMUONPreprocessor(Int_t runNumber=80, const char* runType="PEDESTAL_RUN")
{
  // runType can be :
  //
  // PEDESTAL_RUN -> pedestals
  // ELECTRONICS_CALIBRATION_RUN -> gains
  // PHYSICS -> HV
  // GMS

  // create AliTestShuttle instance
  // The parameters are run, startTime, endTime
  AliTestShuttle* shuttle = new AliTestShuttle(runNumber, 0, 1);

  const char* inputCDB = "local://$ALICE_ROOT/SHUTTLE/TestShuttle/TestCDB";

  AliTestShuttle::SetMainCDB(inputCDB);
  AliTestShuttle::SetMainRefStorage("local://$ALICE_ROOT/SHUTTLE/TestShuttle/TestReference");

  // Create DCS HV aliases
  TMap* dcsAliasMap = CreateDCSAliasMap(inputCDB);

  if ( dcsAliasMap )
  {
    // now give the alias map to the shuttle
    shuttle->SetDCSInput(dcsAliasMap);
  }

  printf("Test Shuttle temp dir: %s\n", AliShuttleInterface::GetShuttleTempDir());
  printf("Test Shuttle log dir: %s\n", AliShuttleInterface::GetShuttleLogDir());
  printf("Test OCDB storage Uri: %s\n", AliShuttleInterface::GetMainCDB().Data());
  printf("Test Reference storage Uri: %s\n", AliShuttleInterface::GetMainRefStorage().Data());

  // The shuttle can process files that originate from DCS, DAQ and HLT.
  // To test it, we provide some local files and locations where these would be found when
  // the online machinery would be there.
  // In real life this functions would be produces by the sub-detectors
  // calibration programs in DCS, DAQ or HLT. These files can then be retrieved using the Shuttle.
  //
  // Files are added with the function AliTestShuttle::AddInputFile. The syntax is:
  // AddInputFile(<system>, <detector>, <id>, <source>, <local-file>)
  // In this example we add 4 files originating from different LDCs but with the same id (PEDESTALS)

  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC0","$ALICE_ROOT/MUON/data/LDC0.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC1","$ALICE_ROOT/MUON/data/LDC1.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC2","$ALICE_ROOT/MUON/data/LDC2.ped");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","PEDESTALS","LDC3","$ALICE_ROOT/MUON/data/LDC3.ped");

  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC0","$ALICE_ROOT/MUON/data/LDC0.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC1","$ALICE_ROOT/MUON/data/LDC1.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC2","$ALICE_ROOT/MUON/data/LDC2.gain");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MCH","GAINS","LDC3","$ALICE_ROOT/MUON/data/LDC3.gain");

  // and GMS file
  shuttle->AddInputFile(AliTestShuttle::kDCS,"MCH","GMS","GMS","$ALICE_ROOT/MUON/data/GMS.root");

  // and then the trigger stuff
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","LOCAL","LDC0","$ALICE_ROOT/MUON/data/MtgLocalMask-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","REGIONAL","LDC0","$ALICE_ROOT/MUON/data/MtgRegionalCrate-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","GLOBAL","LDC0","$ALICE_ROOT/MUON/data/MtgGlobalCrate-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","LUT","LDC0","$ALICE_ROOT/MUON/data/MtgLocalLut-1.dat");
  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MTR","CURRENT","LDC0","$ALICE_ROOT/MUON/data/MtgCurrent.dat");

  // The shuttle can read run parameters stored in the DAQ run logbook.
  // To test it, we must provide the run parameters manually. They will be retrieved in the preprocessor
  // using GetRunParameter function.
  // In real life the parameters will be retrieved automatically from the run logbook;
  shuttle->SetInputRunType(runType);

  // Create the preprocessor that should be tested, it registers itself automatically to the shuttle
  new AliMUONTrackerPreprocessor(shuttle);
  new AliMUONTriggerPreprocessor(shuttle);

  shuttle->Print();

  // Test the preprocessor
  shuttle->Process();
}

TMap* CreateDCSAliasMap(const char* inputCDB)
{
  /// Creates a DCS structure for MUON Tracker HV
  ///
  /// The structure is the following:
  ///   TMap (key --> value)
  ///     <DCSAlias> --> <valueList>
  ///     <DCSAlias> is a string
  ///     <valueList> is a TObjArray of AliDCSValue
  ///     An AliDCSValue consists of timestamp and a value in form of a AliSimpleValue

  Bool_t undefStorage(kFALSE);

  AliCDBManager* man = AliCDBManager::Instance();
  if (!man->IsDefaultStorageSet())
  {
    undefStorage = kTRUE;
    man->SetDefaultStorage(inputCDB);
  }

  // Load mapping
  Bool_t ok = AliMpCDB::LoadDDLStore();

  if (undefStorage)
  {
    man->UnsetDefaultStorage();
  }

  if (!ok)
  {
    AliErrorGeneral("CreateDCSAliasMap","Could not load DDLStore from OCDB");
    return 0x0;
  }

  TMap* aliasMap = new TMap;
  aliasMap->SetOwner(kTRUE);

  TRandom random(0);

  AliMpHVNamer hvNamer;

  TObjArray* aliases = hvNamer.GenerateAliases();

  for ( Int_t i = 0; i < aliases->GetEntries(); ++i )
  {
    TObjString* alias = static_cast<TObjString*>(aliases->At(i));
    TString& aliasName = alias->String();
    if ( aliasName.Contains("sw") )
    {
      // HV Switch (St345 only)
      TObjArray* valueSet = new TObjArray;
      valueSet->SetOwner(kTRUE);
      Bool_t value = kTRUE;
//      Float_t r = random.Uniform();
//      if ( r < 0.007 ) value = kFALSE;
//      if ( aliasName.Contains("DE513sw2") ) value = kFALSE;

      for ( UInt_t timeStamp = 0; timeStamp < 60*3; timeStamp += 60 )
      {
        AliDCSValue* dcsValue = new AliDCSValue(value,timeStamp);
        valueSet->Add(dcsValue);
      }
      aliasMap->Add(new TObjString(*alias),valueSet);
    }
    else
    {
      TObjArray* valueSet = new TObjArray;
      valueSet->SetOwner(kTRUE);
      for ( UInt_t timeStamp = 0; timeStamp < 60*15; timeStamp += 120 )
      {
        Float_t value = random.Gaus(1750,62.5);
        if ( aliasName == "MchHvLvLeft/Chamber00Left/Quad2Sect1.actual.vMon") value = 500;
        AliDCSValue* dcsValue = new AliDCSValue(value,timeStamp);
        valueSet->Add(dcsValue);
      }
      if ( aliasName == "MchHvLvLeft/Chamber04Left/Slat06.actual.vMon" ) continue;
      aliasMap->Add(new TObjString(*alias),valueSet);
    }
  }

  delete aliases;

  return aliasMap;
}

<|endoftext|>