<commit_before>/************************************************************************
  Module:    otherArrays.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
 ************************************************************************/

// All tests need:
//   the following include
//   a Selector proc
//   a Comparator proc
//   a Test proc
//   and a main
#include "rtOtherTestBase.h"

void SelectorCommand(ostream& strm) {
  strm << "grep -v 0x | grep -v Modified ";
}

void ComparatorCommand(ostream& strm) {
  strm << "diff -b";
}
#include "vtkCharArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIntArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkLongArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkShortArray.h"
#include "vtkUnsignedShortArray.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"

#define SIZE 1000

template <class T, class A>
static int doArrayTest (ostream& strm, T *ptr, A *array, int size)
{
  T *ptr2;
  float tuple1[SIZE/100];
  double tuple3[SIZE/100];
  float *tuple2;
  int i;

  strm << "\tSetArray...";
  ptr->SetArray(array, size, 1);
  strm << "OK" << endl;

  strm << "\tSetNumberOfTuples...";
  ptr->SetNumberOfTuples (100);
  if (ptr->GetNumberOfTuples() == 100) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetNumberOfComponents...";
  ptr->SetNumberOfComponents (10);
  if (ptr->GetNumberOfComponents() == 10) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tMakeObject...";
  if (ptr2 = ptr->SafeDownCast(ptr->MakeObject()))
    {
    if (ptr2->GetNumberOfComponents() == 10) strm << "OK" << endl;
    else strm << "FAILED" << endl;
    }
  else
    {
    strm << "FAILED" << endl;
    }

  strm << "\tGetTuple(i)...";
  tuple2 = ptr->GetTuple (2);
  int passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << *(tuple2 + i) << " ";
    if (*(tuple2 + i) != (20 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tGetTuple(i, float *tuple)...";
  ptr->GetTuple (3, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tGetTuple(i, double *tuple)...";
  ptr->GetTuple (4, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::GetTuple(i, double *tuple)...";
  ptr->vtkDataArray::GetTuple (4, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetTuple(i, float *tuple)...";
  ptr->SetTuple (99, tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (99, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetTuple(i, double *tuple)...";
  ptr->SetTuple (99, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (99, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::SetTuple(i, double *tuple)...";
  ptr->vtkDataArray::SetTuple (99, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (99, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertTuple(i, float *tuple)...";
  ptr->InsertTuple (100, tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (100, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertTuple(i, double *tuple)...";
  ptr->InsertTuple (100, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (100, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::InsertTuple(i, double *tuple)...";
  ptr->vtkDataArray::InsertTuple (100, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (100, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertNextTuple(float *tuple)...";
  ptr->InsertNextTuple (tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (101, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertNextTuple(double *tuple)...";
  ptr->InsertNextTuple (tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (102, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::InsertNextTuple(double *tuple)...";
  ptr->vtkDataArray::InsertNextTuple (tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (102, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::GetData...";
  vtkFloatArray *farray = vtkFloatArray::New();
  farray->SetNumberOfComponents(1);
  ptr->vtkDataArray::GetData (0, 59, 1, 1, *farray);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << farray->GetTuple(i)[0] << " ";
    if (farray->GetTuple(i)[0] != (1 + i*10))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;
  farray->Delete();

  strm << "PrintSelf..." << endl;
  strm << *ptr;

  return 0;
}

void Test(ostream& strm)
{
  {
  strm << "Test CharArray" << endl;
  vtkCharArray *ptr = vtkCharArray::New();
  char *array = new char[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedCharArray" << endl;
  vtkUnsignedCharArray *ptr = vtkUnsignedCharArray::New();
  unsigned char *array = new unsigned char[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test IntArray" << endl;
  vtkIntArray *ptr = vtkIntArray::New();
  int *array = new int[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedIntArray" << endl;
  vtkUnsignedIntArray *ptr = vtkUnsignedIntArray::New();
  unsigned int *array = new unsigned int[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test LongArray" << endl;
  vtkLongArray *ptr = vtkLongArray::New();
  long *array = new long[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedLongArray" << endl;
  vtkUnsignedLongArray *ptr = vtkUnsignedLongArray::New();
  unsigned long *array = new unsigned long[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test ShortArray" << endl;
  vtkShortArray *ptr = vtkShortArray::New();
  short *array = new short[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedShortArray" << endl;
  vtkUnsignedShortArray *ptr = vtkUnsignedShortArray::New();
  unsigned short *array = new unsigned short[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test FloatArray" << endl;
  vtkFloatArray *ptr = vtkFloatArray::New();
  float *array = new float[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test DoubleArray" << endl;
  vtkDoubleArray *ptr = vtkDoubleArray::New();
  double *array = new double[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

}

int main(int argc, char* argv[])
{
  rtOtherTestBase::RunTest(argc, argv, SelectorCommand, ComparatorCommand, Test);

  return 0;
}
<commit_msg>It was using deprecated version of GetData<commit_after>/************************************************************************
  Module:    otherArrays.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$
 ************************************************************************/

// All tests need:
//   the following include
//   a Selector proc
//   a Comparator proc
//   a Test proc
//   and a main
#include "rtOtherTestBase.h"

void SelectorCommand(ostream& strm) {
  strm << "grep -v 0x | grep -v Modified ";
}

void ComparatorCommand(ostream& strm) {
  strm << "diff -b";
}
#include "vtkCharArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIntArray.h"
#include "vtkUnsignedIntArray.h"
#include "vtkLongArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkShortArray.h"
#include "vtkUnsignedShortArray.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"

#define SIZE 1000

template <class T, class A>
static int doArrayTest (ostream& strm, T *ptr, A *array, int size)
{
  T *ptr2;
  float tuple1[SIZE/100];
  double tuple3[SIZE/100];
  float *tuple2;
  int i;

  strm << "\tSetArray...";
  ptr->SetArray(array, size, 1);
  strm << "OK" << endl;

  strm << "\tSetNumberOfTuples...";
  ptr->SetNumberOfTuples (100);
  if (ptr->GetNumberOfTuples() == 100) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetNumberOfComponents...";
  ptr->SetNumberOfComponents (10);
  if (ptr->GetNumberOfComponents() == 10) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tMakeObject...";
  if (ptr2 = ptr->SafeDownCast(ptr->MakeObject()))
    {
    if (ptr2->GetNumberOfComponents() == 10) strm << "OK" << endl;
    else strm << "FAILED" << endl;
    }
  else
    {
    strm << "FAILED" << endl;
    }

  strm << "\tGetTuple(i)...";
  tuple2 = ptr->GetTuple (2);
  int passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << *(tuple2 + i) << " ";
    if (*(tuple2 + i) != (20 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tGetTuple(i, float *tuple)...";
  ptr->GetTuple (3, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tGetTuple(i, double *tuple)...";
  ptr->GetTuple (4, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::GetTuple(i, double *tuple)...";
  ptr->vtkDataArray::GetTuple (4, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetTuple(i, float *tuple)...";
  ptr->SetTuple (99, tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (99, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tSetTuple(i, double *tuple)...";
  ptr->SetTuple (99, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (99, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::SetTuple(i, double *tuple)...";
  ptr->vtkDataArray::SetTuple (99, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (99, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertTuple(i, float *tuple)...";
  ptr->InsertTuple (100, tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (100, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertTuple(i, double *tuple)...";
  ptr->InsertTuple (100, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (100, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::InsertTuple(i, double *tuple)...";
  ptr->vtkDataArray::InsertTuple (100, tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (100, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertNextTuple(float *tuple)...";
  ptr->InsertNextTuple (tuple1);
  for (i=0; i < 10; i++) tuple1[i] = 0;
  ptr->GetTuple (101, tuple1);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple1[i] << " ";
    if (tuple1[i] != (30 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tInsertNextTuple(double *tuple)...";
  ptr->InsertNextTuple (tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (102, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::InsertNextTuple(double *tuple)...";
  ptr->vtkDataArray::InsertNextTuple (tuple3);
  for (i=0; i < 10; i++) tuple3[i] = 0;
  ptr->GetTuple (102, tuple3);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << tuple3[i] << " ";
    if (tuple3[i] != (40 + i))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;

  strm << "\tvtkDataArray::GetData...";
  vtkFloatArray *farray = vtkFloatArray::New();
  farray->SetNumberOfComponents(1);
  ptr->vtkDataArray::GetData (0, 59, 1, 1,  farray);
  passed = 1;
  for (i = 0; i < 10; i++)
    {
    strm << farray->GetTuple(i)[0] << " ";
    if (farray->GetTuple(i)[0] != (1 + i*10))
      {
      passed = 0;
      break;
      }
    }
  if (passed) strm << "OK" << endl;
  else strm << "FAILED" << endl;
  farray->Delete();

  strm << "PrintSelf..." << endl;
  strm << *ptr;

  return 0;
}

void Test(ostream& strm)
{
  {
  strm << "Test CharArray" << endl;
  vtkCharArray *ptr = vtkCharArray::New();
  char *array = new char[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedCharArray" << endl;
  vtkUnsignedCharArray *ptr = vtkUnsignedCharArray::New();
  unsigned char *array = new unsigned char[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test IntArray" << endl;
  vtkIntArray *ptr = vtkIntArray::New();
  int *array = new int[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedIntArray" << endl;
  vtkUnsignedIntArray *ptr = vtkUnsignedIntArray::New();
  unsigned int *array = new unsigned int[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test LongArray" << endl;
  vtkLongArray *ptr = vtkLongArray::New();
  long *array = new long[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedLongArray" << endl;
  vtkUnsignedLongArray *ptr = vtkUnsignedLongArray::New();
  unsigned long *array = new unsigned long[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test ShortArray" << endl;
  vtkShortArray *ptr = vtkShortArray::New();
  short *array = new short[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test UnsignedShortArray" << endl;
  vtkUnsignedShortArray *ptr = vtkUnsignedShortArray::New();
  unsigned short *array = new unsigned short[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test FloatArray" << endl;
  vtkFloatArray *ptr = vtkFloatArray::New();
  float *array = new float[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

  {
  strm << "Test DoubleArray" << endl;
  vtkDoubleArray *ptr = vtkDoubleArray::New();
  double *array = new double[SIZE];
  for (int i = 0; i < SIZE; i++) *(array + i ) = i;
  doArrayTest (strm, ptr, array, SIZE);
  ptr->Delete();
  delete []array;
  }

}

int main(int argc, char* argv[])
{
  rtOtherTestBase::RunTest(argc, argv, SelectorCommand, ComparatorCommand, Test);

  return 0;
}
<|endoftext|>


<commit_before>/// \file stream.cpp
/// Utilities for handling streams.

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include "json.h"
#include "stream.h"
#include "procs.h"
#include "config.h"
#include "socket.h"
#include "defines.h"

std::string Util::getTmpFolder(){
  std::string dir;
  char * tmp_char = 0;
  if ( !tmp_char){
    tmp_char = getenv("TMP");
  }
  if ( !tmp_char){
    tmp_char = getenv("TEMP");
  }
  if ( !tmp_char){
    tmp_char = getenv("TMPDIR");
  }
  if (tmp_char){
    dir = tmp_char;
    dir += "/mist";
  }else{
#if defined(_WIN32) || defined(_CYGWIN_)
    dir = "C:/tmp/mist";
#else
    dir = "/tmp/mist";
#endif
  }
  if (access(dir.c_str(), 0) != 0){
    mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); //attempt to create mist folder - ignore failures
  }
  return dir + "/";
}

/// Filters the streamname, removing invalid characters and converting all
/// letters to lowercase. If a '?' character is found, everything following
/// that character is deleted. The original string is modified.
void Util::Stream::sanitizeName(std::string & streamname){
  //strip anything that isn't numbers, digits or underscores
  for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i){
    if ( *i == '?'){
      streamname.erase(i, streamname.end());
      break;
    }
    if ( !isalpha( *i) && !isdigit( *i) && *i != '_'){
      streamname.erase(i);
    }else{
      *i = tolower( *i);
    }
  }
}

Socket::Connection Util::Stream::getLive(std::string streamname){
  return Socket::Connection(getTmpFolder() + "stream_" + streamname);
}

/// Starts a process for a VoD stream.
Socket::Connection Util::Stream::getVod(std::string filename, std::string streamname){
  std::string name = "MistPlayer " + filename;
  std::string player_bin = Util::getMyPath() + "MistPlayer";
  char* const argv[] = {(char*)player_bin.c_str(), (char*)filename.c_str(), (char*)"-s", (char*)streamname.c_str(), (char*)0};
  int fdin = -1, fdout = -1, fderr = fileno(stderr);
  Util::Procs::StartPiped(name, argv, &fdin, &fdout, &fderr);
  // if StartPiped fails then fdin and fdout will be unmodified (-1)
  return Socket::Connection(fdin, fdout);
}

/// Probe for available streams. Currently first VoD, then Live.
Socket::Connection Util::Stream::getStream(std::string streamname){
  sanitizeName(streamname);
  JSON::Value ServConf = JSON::fromFile(getTmpFolder() + "streamlist");
  if (ServConf["streams"].isMember(streamname)){
    if (ServConf["streams"][streamname]["source"].asString()[0] == '/'){
      return getVod(ServConf["streams"][streamname]["source"].asString(), streamname);
    }else{
      return Socket::Connection(getTmpFolder() + "stream_" + streamname);
    }
  }
  DEBUG_MSG(DLVL_ERROR, "Stream not found: %s", streamname.c_str());
  return Socket::Connection();
}

/// Create a stream on the system.
/// Filters the streamname, removing invalid characters and
/// converting all letters to lowercase.
/// If a '?' character is found, everything following that character is deleted.
Socket::Server Util::Stream::makeLive(std::string streamname){
  sanitizeName(streamname);
  std::string loc = getTmpFolder() + "stream_" + streamname;
  //create and return the Socket::Server
  return Socket::Server(loc);
}
<commit_msg>Fixed threaded use of MistPlayer.<commit_after>/// \file stream.cpp
/// Utilities for handling streams.

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include "json.h"
#include "stream.h"
#include "procs.h"
#include "config.h"
#include "socket.h"
#include "defines.h"

std::string Util::getTmpFolder(){
  std::string dir;
  char * tmp_char = 0;
  if ( !tmp_char){
    tmp_char = getenv("TMP");
  }
  if ( !tmp_char){
    tmp_char = getenv("TEMP");
  }
  if ( !tmp_char){
    tmp_char = getenv("TMPDIR");
  }
  if (tmp_char){
    dir = tmp_char;
    dir += "/mist";
  }else{
#if defined(_WIN32) || defined(_CYGWIN_)
    dir = "C:/tmp/mist";
#else
    dir = "/tmp/mist";
#endif
  }
  if (access(dir.c_str(), 0) != 0){
    mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); //attempt to create mist folder - ignore failures
  }
  return dir + "/";
}

/// Filters the streamname, removing invalid characters and converting all
/// letters to lowercase. If a '?' character is found, everything following
/// that character is deleted. The original string is modified.
void Util::Stream::sanitizeName(std::string & streamname){
  //strip anything that isn't numbers, digits or underscores
  for (std::string::iterator i = streamname.end() - 1; i >= streamname.begin(); --i){
    if ( *i == '?'){
      streamname.erase(i, streamname.end());
      break;
    }
    if ( !isalpha( *i) && !isdigit( *i) && *i != '_'){
      streamname.erase(i);
    }else{
      *i = tolower( *i);
    }
  }
}

Socket::Connection Util::Stream::getLive(std::string streamname){
  return Socket::Connection(getTmpFolder() + "stream_" + streamname);
}

/// Starts a process for a VoD stream.
Socket::Connection Util::Stream::getVod(std::string filename, std::string streamname){
  static unsigned long long counter = 0;
  std::stringstream name;
  name << "MistPlayer " << (counter++);
  std::string player_bin = Util::getMyPath() + "MistPlayer";
  char* const argv[] = {(char*)player_bin.c_str(), (char*)filename.c_str(), (char*)"-s", (char*)streamname.c_str(), (char*)0};
  int fdin = -1, fdout = -1, fderr = fileno(stderr);
  Util::Procs::StartPiped(name.str(), argv, &fdin, &fdout, &fderr);
  // if StartPiped fails then fdin and fdout will be unmodified (-1)
  return Socket::Connection(fdin, fdout);
}

/// Probe for available streams. Currently first VoD, then Live.
Socket::Connection Util::Stream::getStream(std::string streamname){
  sanitizeName(streamname);
  JSON::Value ServConf = JSON::fromFile(getTmpFolder() + "streamlist");
  if (ServConf["streams"].isMember(streamname)){
    if (ServConf["streams"][streamname]["source"].asString()[0] == '/'){
      return getVod(ServConf["streams"][streamname]["source"].asString(), streamname);
    }else{
      return Socket::Connection(getTmpFolder() + "stream_" + streamname);
    }
  }
  DEBUG_MSG(DLVL_ERROR, "Stream not found: %s", streamname.c_str());
  return Socket::Connection();
}

/// Create a stream on the system.
/// Filters the streamname, removing invalid characters and
/// converting all letters to lowercase.
/// If a '?' character is found, everything following that character is deleted.
Socket::Server Util::Stream::makeLive(std::string streamname){
  sanitizeName(streamname);
  std::string loc = getTmpFolder() + "stream_" + streamname;
  //create and return the Socket::Server
  return Socket::Server(loc);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * cmd_quit.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
#   include "config.h"
#endif

#include <vlc_osd.h>
#include <vlc_playlist.h>

#include "cmd_quit.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_loop.hpp"

void CmdQuit::execute()
{
    // Stop the playlist
    vout_OSDMessage( getIntf(), DEFAULT_CHAN, _( "Quit" ) );
    playlist_Stop( getIntf()->p_sys->p_playlist );

    // Get the instance of OSFactory
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );

    // Exit the main OS loop
    pOsFactory->getOSLoop()->exit();

    // Kill libvlc
    vlc_object_kill( getIntf()->p_libvlc );
}
<commit_msg>Fix quit sequence in skins2.<commit_after>/*****************************************************************************
 * cmd_quit.cpp
 *****************************************************************************
 * Copyright (C) 2003 the VideoLAN team
 * $Id$
 *
 * Authors: Cyril Deguet     <asmax@via.ecp.fr>
 *          Olivier Teulière <ipkiss@via.ecp.fr>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
#   include "config.h"
#endif

#include <vlc_osd.h>
#include <vlc_playlist.h>

#include "cmd_quit.hpp"
#include "../src/os_factory.hpp"
#include "../src/os_loop.hpp"

void CmdQuit::execute()
{
    // Stop the playlist
    vout_OSDMessage( getIntf(), DEFAULT_CHAN, _( "Quit" ) );

    // Get the instance of OSFactory
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );

    // Exit the main OS loop
    pOsFactory->getOSLoop()->exit();

    // Kill libvlc
    vlc_object_kill( getIntf()->p_libvlc );
}
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_ACTOR_FACADE_HPP
#define CPPA_OPENCL_ACTOR_FACADE_HPP

#include <ostream>
#include <stdexcept>

#include "cppa/cppa.hpp"

#include "cppa/channel.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/intrusive_ptr.hpp"

#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/scope_guard.hpp"

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp"
#include "cppa/opencl/program.hpp"
#include "cppa/opencl/smart_ptr.hpp"

#include "cppa/detail/scheduled_actor_dummy.hpp"

namespace cppa { namespace opencl {

class command_dispatcher;

void enqueue_to_dispatcher(command_dispatcher*, command_ptr);

template<typename Signature>
class actor_facade;

template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public actor {

 public:

    /*
    actor_facade(command_dispatcher* dispatcher,
                 const program& prog,
                 const char* kernel_name)
        : m_program(prog.m_program)
        , m_context(prog.m_context)
        , m_dispatcher(dispatcher)
    {
        CPPA_LOG_TRACE("new actor facde with ID " << this->id());
        init_kernel(m_program.get(), kernel_name);
    }

    actor_facade(command_dispatcher* dispatcher,
                 const program& prog,
                 const char* kernel_name,
                 std::vector<size_t>& global_dimensions,
                 std::vector<size_t>& local_dimensions)
        : m_program(prog.m_program)
        , m_context(prog.m_context)
        , m_dispatcher(dispatcher)
        , m_global_dimensions(global_dimensions)
        , m_local_dimensions(local_dimensions)
    {
        CPPA_LOG_TRACE("new actor facde with ID " << this->id());
        if(m_local_dimensions .size() > 3 ||
           m_global_dimensions.size() > 3) {
            std::ostringstream oss;
            oss << "Creating actor facade: a maximum of 3 dimensions allowed.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        init_kernel(m_program.get(), kernel_name);
    }
    */

    actor_facade(command_dispatcher* dispatcher,
                 const program& prog,
                 const char* kernel_name,
                 std::vector<size_t> global_dimensions,
                 std::vector<size_t> local_dimensions,
                 std::function<option<cow_tuple<typename util::rm_ref<Args>::type...>>(any_tuple)> map_args,
                 std::function<any_tuple(Ret&)> map_result)
                 //std::function<option<cow_tuple<Args...>>(any_tuple)> map_args,
                 //std::function<any_tuple(Ret& result)> map_result)
      : m_program(prog.m_program)
      , m_context(prog.m_context)
      , m_dispatcher(dispatcher)
      , m_global_dimensions(std::move(global_dimensions))
      , m_local_dimensions(std::move(local_dimensions))
      , m_map_args(std::move(map_args))
      , m_map_result(std::move(map_result))
    {
        CPPA_LOG_TRACE("new actor facde with ID " << this->id());
        if(m_local_dimensions .size() > 3 ||
           m_global_dimensions.size() > 3) {
            std::ostringstream oss;
            oss << "Creating actor facade: a maximum of 3 dimensions allowed.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        init_kernel(m_program.get(), kernel_name);
    }

    void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg) {
        CPPA_LOG_TRACE("actor_facade::sync_enqueue()");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, id, indices);
    }

    void enqueue(const actor_ptr& sender, any_tuple msg) {
        CPPA_LOG_TRACE("actor_facade::enqueue()");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, message_id{}, indices);
    }

 private:

    void init_kernel(cl_program program, const char* kernel_name) {
        cl_int err{0};
        m_kernel.adopt(clCreateKernel(program,
                                      kernel_name,
                                      &err));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateKernel: '"
              << get_opencl_error(err)
              << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
    }

    template<long... Is>
    void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
        //auto opt = tuple_cast<Args...>(msg);
        auto opt = m_map_args(msg);
        if (opt) {
            response_handle handle{this, sender, id};
            size_t number_of_values = 1;
            if (!m_global_dimensions.empty()) {
                for (auto s : m_global_dimensions) {
                    number_of_values *= s;
                }
            }
            else {
                number_of_values = get<0>(*opt).size();
                m_global_dimensions.push_back(number_of_values);
                m_global_dimensions.push_back(1);
                m_global_dimensions.push_back(1);
            }
            if (m_global_dimensions.empty() || number_of_values <= 0) {
                std::ostringstream oss;
                oss << "actor_facade::enqueue() can't handle dimension sizes!";
                CPPA_LOG_ERROR(oss.str());
                throw std::runtime_error(oss.str());
            }
            Ret result_buf(number_of_values);
            std::vector<mem_ptr> arguments;
            add_arguments_to_kernel(arguments,
                                    m_context.get(),
                                    m_kernel.get(),
                                    result_buf,
                                    get_ref<Is>(*opt)...);
            CPPA_LOG_TRACE("enqueue to dispatcher");
            enqueue_to_dispatcher(m_dispatcher,
                                  make_counted<command_impl<Ret>>(handle,
                                                                  m_kernel,
                                                                  arguments,
                                                                  m_global_dimensions,
                                                                  m_local_dimensions,
                                                                  m_map_result));
        }
        else {
            CPPA_LOG_ERROR("actor_facade::enqueue() tuple_cast failed.");
        }
    }

    typedef std::vector<mem_ptr> args_vec;

    program_ptr m_program;
    kernel_ptr m_kernel;
    context_ptr m_context;
    command_dispatcher* m_dispatcher;
    std::vector<size_t> m_global_dimensions;
    std::vector<size_t> m_local_dimensions;
    std::function<option<cow_tuple<Args...>>(any_tuple)> m_map_args;
    std::function<any_tuple(Ret& result)> m_map_result;

    void add_arguments_to_kernel_rec(args_vec& arguments,
                                            cl_context,
                                            cl_kernel kernel) {
        cl_int err{0};
        for(unsigned long i{1}; i < arguments.size(); ++i) {
            err = clSetKernelArg(kernel,
                                 (i-1),
                                 sizeof(cl_mem),
                                 static_cast<void*>(&arguments[i]));
            if (err != CL_SUCCESS) {
                std::ostringstream oss;
                oss << "clSetKernelArg: '"
                    << get_opencl_error(err)
                    << "'.";
                CPPA_LOG_ERROR(oss.str());
                throw std::runtime_error(oss.str());
            }
        }
        err = clSetKernelArg(kernel,
                             arguments.size()-1,
                             sizeof(cl_mem),
                             static_cast<void*>(&arguments[0]));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clSetKernelArg: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
    }

    template<typename T0, typename... Ts>
    void add_arguments_to_kernel_rec(args_vec& arguments,
                                            cl_context context,
                                            cl_kernel kernel,
                                            T0& arg0,
                                            Ts&... args) {
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  sizeof(typename T0::value_type)*arg0.size(),
                                  arg0.data(),
                                  &err);
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateBuffer: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            return add_arguments_to_kernel_rec(arguments,
                                               context,
                                               kernel,
                                               args...);
        }
    }

    template<typename R, typename... Ts>
    void add_arguments_to_kernel(args_vec& arguments,
                                        cl_context context,
                                        cl_kernel kernel,
                                        R& ret,
                                        Ts&&... args) {
        arguments.clear();
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_WRITE_ONLY,
                                  sizeof(typename R::value_type)*ret.size(),
                                  nullptr,
                                  &err);
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateBuffer: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            return add_arguments_to_kernel_rec(arguments,
                                               context,
                                               kernel,
                                               std::forward<Ts>(args)...);
        }
    }

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_ACTOR_FACADE_HPP
<commit_msg>fixed type of mapping functor<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011-2013                                                    *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 * Raphael Hiesgen <raphael.hiesgen@haw-hamburg.de>                           *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa is distributed in the hope that it will be useful,                 *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       *
 * See the GNU Lesser General Public License for more details.                *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_OPENCL_ACTOR_FACADE_HPP
#define CPPA_OPENCL_ACTOR_FACADE_HPP

#include <ostream>
#include <stdexcept>

#include "cppa/cppa.hpp"

#include "cppa/channel.hpp"
#include "cppa/to_string.hpp"
#include "cppa/tuple_cast.hpp"
#include "cppa/intrusive_ptr.hpp"

#include "cppa/util/int_list.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/scope_guard.hpp"

#include "cppa/opencl/global.hpp"
#include "cppa/opencl/command.hpp"
#include "cppa/opencl/program.hpp"
#include "cppa/opencl/smart_ptr.hpp"

#include "cppa/detail/scheduled_actor_dummy.hpp"

namespace cppa { namespace opencl {

class command_dispatcher;

void enqueue_to_dispatcher(command_dispatcher*, command_ptr);

template<typename Signature>
class actor_facade;

template<typename Ret, typename... Args>
class actor_facade<Ret(Args...)> : public actor {

 public:

    typedef cow_tuple<typename util::rm_ref<Args>::type...> args_tuple;
    typedef std::function<option<args_tuple>(any_tuple)> arg_mapping;
    typedef std::function<any_tuple(Ret&)> result_mapping;

    actor_facade(command_dispatcher* dispatcher,
                 const program& prog,
                 const char* kernel_name,
                 std::vector<size_t> global_dimensions,
                 std::vector<size_t> local_dimensions,
                 arg_mapping map_args,
                 result_mapping map_result)
      : m_program(prog.m_program)
      , m_context(prog.m_context)
      , m_dispatcher(dispatcher)
      , m_global_dimensions(std::move(global_dimensions))
      , m_local_dimensions(std::move(local_dimensions))
      , m_map_args(std::move(map_args))
      , m_map_result(std::move(map_result))
    {
        CPPA_LOG_TRACE("new actor facde with ID " << this->id());
        if(m_local_dimensions .size() > 3 ||
           m_global_dimensions.size() > 3) {
            std::ostringstream oss;
            oss << "Creating actor facade: a maximum of 3 dimensions allowed.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        init_kernel(m_program.get(), kernel_name);
    }

    void sync_enqueue(const actor_ptr& sender, message_id id, any_tuple msg) {
        CPPA_LOG_TRACE("actor_facade::sync_enqueue()");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, id, indices);
    }

    void enqueue(const actor_ptr& sender, any_tuple msg) {
        CPPA_LOG_TRACE("actor_facade::enqueue()");
        typename util::il_indices<util::type_list<Args...>>::type indices;
        enqueue_impl(sender, msg, message_id{}, indices);
    }

 private:

    void init_kernel(cl_program program, const char* kernel_name) {
        cl_int err{0};
        m_kernel.adopt(clCreateKernel(program,
                                      kernel_name,
                                      &err));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateKernel: '"
              << get_opencl_error(err)
              << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
    }

    template<long... Is>
    void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
        //auto opt = tuple_cast<Args...>(msg);
        auto opt = m_map_args(msg);
        if (opt) {
            response_handle handle{this, sender, id};
            size_t number_of_values = 1;
            if (!m_global_dimensions.empty()) {
                for (auto s : m_global_dimensions) {
                    number_of_values *= s;
                }
            }
            else {
                number_of_values = get<0>(*opt).size();
                m_global_dimensions.push_back(number_of_values);
                m_global_dimensions.push_back(1);
                m_global_dimensions.push_back(1);
            }
            if (m_global_dimensions.empty() || number_of_values <= 0) {
                std::ostringstream oss;
                oss << "actor_facade::enqueue() can't handle dimension sizes!";
                CPPA_LOG_ERROR(oss.str());
                throw std::runtime_error(oss.str());
            }
            Ret result_buf(number_of_values);
            std::vector<mem_ptr> arguments;
            add_arguments_to_kernel(arguments,
                                    m_context.get(),
                                    m_kernel.get(),
                                    result_buf,
                                    get_ref<Is>(*opt)...);
            CPPA_LOG_TRACE("enqueue to dispatcher");
            enqueue_to_dispatcher(m_dispatcher,
                                  make_counted<command_impl<Ret>>(handle,
                                                                  m_kernel,
                                                                  arguments,
                                                                  m_global_dimensions,
                                                                  m_local_dimensions,
                                                                  m_map_result));
        }
        else {
            CPPA_LOG_ERROR("actor_facade::enqueue() tuple_cast failed.");
        }
    }

    typedef std::vector<mem_ptr> args_vec;

    program_ptr m_program;
    kernel_ptr m_kernel;
    context_ptr m_context;
    command_dispatcher* m_dispatcher;
    std::vector<size_t> m_global_dimensions;
    std::vector<size_t> m_local_dimensions;
    arg_mapping m_map_args;
    result_mapping m_map_result;

    void add_arguments_to_kernel_rec(args_vec& arguments,
                                            cl_context,
                                            cl_kernel kernel) {
        cl_int err{0};
        for(unsigned long i{1}; i < arguments.size(); ++i) {
            err = clSetKernelArg(kernel,
                                 (i-1),
                                 sizeof(cl_mem),
                                 static_cast<void*>(&arguments[i]));
            if (err != CL_SUCCESS) {
                std::ostringstream oss;
                oss << "clSetKernelArg: '"
                    << get_opencl_error(err)
                    << "'.";
                CPPA_LOG_ERROR(oss.str());
                throw std::runtime_error(oss.str());
            }
        }
        err = clSetKernelArg(kernel,
                             arguments.size()-1,
                             sizeof(cl_mem),
                             static_cast<void*>(&arguments[0]));
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clSetKernelArg: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
    }

    template<typename T0, typename... Ts>
    void add_arguments_to_kernel_rec(args_vec& arguments,
                                            cl_context context,
                                            cl_kernel kernel,
                                            T0& arg0,
                                            Ts&... args) {
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                                  sizeof(typename T0::value_type)*arg0.size(),
                                  arg0.data(),
                                  &err);
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateBuffer: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            return add_arguments_to_kernel_rec(arguments,
                                               context,
                                               kernel,
                                               args...);
        }
    }

    template<typename R, typename... Ts>
    void add_arguments_to_kernel(args_vec& arguments,
                                        cl_context context,
                                        cl_kernel kernel,
                                        R& ret,
                                        Ts&&... args) {
        arguments.clear();
        cl_int err{0};
        auto buf = clCreateBuffer(context,
                                  CL_MEM_WRITE_ONLY,
                                  sizeof(typename R::value_type)*ret.size(),
                                  nullptr,
                                  &err);
        if (err != CL_SUCCESS) {
            std::ostringstream oss;
            oss << "clCreateBuffer: '"
                << get_opencl_error(err)
                << "'.";
            CPPA_LOG_ERROR(oss.str());
            throw std::runtime_error(oss.str());
        }
        else {
            mem_ptr tmp;
            tmp.adopt(std::move(buf));
            arguments.push_back(tmp);
            return add_arguments_to_kernel_rec(arguments,
                                               context,
                                               kernel,
                                               std::forward<Ts>(args)...);
        }
    }

};

} } // namespace cppa::opencl

#endif // CPPA_OPENCL_ACTOR_FACADE_HPP
<|endoftext|>


<commit_before>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/

/* Originally by Brad Garton, Doug Scott, and Dave Topper.
   Reworked for v2.3 by John Gibson.
*/
#include <globals.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sndlibsupport.h>
#include <rtdefs.h>
#ifdef LINUX
   #include <fcntl.h>
#endif /* LINUX */
#ifdef SGI
   #include <dmedia/audio.h>
#endif /* SGI */

/* code that lets user specify buses for input sources */
//#define INPUT_BUS_SUPPORT

typedef enum {
   MIC,
   LINE,
   DIGITAL
} AudioPortType;

#ifdef LINUX
   #define open_audio_input open_linux_audio_input
#endif
#ifdef SGI
   #define open_audio_input open_sgi_audio_input
#endif

static last_input_index = -1;

/* ------------------------------------------------- get_last_inpud_index --- */
/* Called by rtsetinput to find out which file to set for the inst.
*/
int
get_last_input_index()
{
   return last_input_index;
}

#ifdef LINUX
/* ----------------------------------------------- open_linux_audio_input --- */
/* The device has already been opened in rtsetparams.
*/
static int
open_linux_audio_input()
{
   if (in_port)
      return in_port;         /* global set in rtsetparams */
   else
      return -1;
}
#endif /* LINUX */

#ifdef SGI
/* ------------------------------------------------- open_sgi_audio_input --- */
/*
   <port_type> is one of AL_INPUT_MIC, AL_INPUT_LINE, or AL_INPUT_DIGITAL.
*/
static int
open_sgi_audio_input(AudioPortType port_type, int nchans)
{
   int      port;
   long     pvbuf[4];
   long     buflen;
   ALconfig in_port_config;

   /* configure and open input audio port */
   in_port_config = ALnewconfig();
   ALsetwidth(in_port_config, AL_SAMPLE_16);

   if (nchans == 1)
      ALsetchannels(in_port_config, AL_MONO);
   else (nchans == 2)
      ALsetchannels(in_port_config, AL_STEREO);

   if (ALsetqueuesize(in_port_config, RTBUFSAMPS * 4) == -1) {
      fprintf(stderr,
              "Could not configure the input audio port queue size to %d.\n",
              RTBUFSAMPS * 4);
      return -1;
   }

   switch (port_type) {
      case LINE:
         port = AL_INPUT_LINE;
         break;
      case DIGITAL:
         port = AL_INPUT_DIGITAL;
         break;
      default:
         port = AL_INPUT_MIC;
         break;
   }

   pvbuf[0] = AL_INPUT_RATE;
   pvbuf[1] = (long) SR;
   pvbuf[2] = AL_INPUT_SOURCE;
   pvbuf[3] = port;
   buflen = 4;

   ALsetparams(AL_DEFAULT_DEVICE, pvbuf, buflen);

   /* open up thet thar audio port! */
   in_port = ALopenport("rtcmixin", "r", in_port_config);

   ALfreeconfig(in_port_config);

   if (!in_port) {
      fprintf(stderr, "Could not open input audio port.\n");
      return -1;
   }

   return AUDIO_DEVICE_ID;          /* our fake fd for SGI audio devices */
}
#endif /* SGI */

/* ------------------------------------------------------ open_sound_file --- */
static int
open_sound_file(
      char     *sfname,
      int      *header_type,
      int      *data_format,
      int      *data_location,
      double   *srate,
      int      *nchans,
      long     *nsamps)
{
   int         fd;
   struct stat sfst;

   /* See if file exists and is a regular file or link. */
   if (stat(sfname, &sfst) == -1) {
      fprintf(stderr, "%s: %s\n", sfname, strerror(errno));
      return -1;
   }
   if (!S_ISREG(sfst.st_mode) && !S_ISLNK(sfst.st_mode)) {
      fprintf(stderr, "%s is not a regular file or a link.\n", sfname);
      return -1;
   }

   /* Open the file and read its header. */
   fd = sndlib_open_read(sfname);
   if (fd == -1) {
      fprintf(stderr, "Can't read header of \"%s\" (%s)\n",
                                                  sfname, strerror(errno));
      return -1;
   }

   /* Now info is available from sndlib query functions. */

   *header_type = c_snd_header_type();

   if (NOT_A_SOUND_FILE(*header_type)) {
      fprintf(stderr, "\"%s\" is probably not a sound file\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }

   *data_format = c_snd_header_format();

   if (INVALID_DATA_FORMAT(*data_format)) {
      fprintf(stderr, "\"%s\" has invalid sound data format\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }
#ifdef NOMORE  // float input should work now -JG
   if (IS_FLOAT_FORMAT(*data_format)) {
      fprintf(stderr, "\"%s\": can't handle float input files yet.\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }
#endif

   *data_location = c_snd_header_data_location();
   *srate = (double) c_snd_header_srate();
   *nchans = c_snd_header_chans();
   *nsamps = c_snd_header_data_size();

   return fd;
}

/* -------------------------------------------------------------- rtinput --- */
/* This function is used in the score to open a file or an audio device for
   subsequent reads by RT Instruments. "rtsetinput" is used in
   the init member functions of the Instruments to access the file.

   p[0] is either a sound file name or "AUDIO" (for an audio device).

   If it's "AUDIO", then p[1] (optional) can be "MIC", "LINE" or
   "DIGITAL". (This option not available yet under Linux.)
   This sets up the input device to do real-time reading of sound.

FIXME: this stuff not implemented yet  -JGG
   pfields after these are bus specification strings in the format
   accepted by the bus_config Minc function. They *must* be "in"
   buses, not "auxin". The bus spec. is optional - if absent, the
   default is "in0-X", where `X' is the number of channels in the
   sound file; "AUDIO" input defaults to stereo ("in0-1").

   Note that the only reason to bother with the bus specification
   is to make it possible to have more than one input source for
   an instrument.
*/
double
rtinput(float p[], int n_args, double pp[])
{
   int            i, j, anint, audio_in, p1_is_audioport, start_pfield, fd;
   int            is_open, header_type, data_format, data_location, nchans;
#ifdef INPUT_BUS_SUPPORT
   int            startchan, endchan;
   short          busindex, buslist[MAXBUS];
   BusType        type;
#endif /* INPUT_BUS_SUPPORT */
   long           nsamps;
   double         srate, dur;
   char           *sfname, *str;
   AudioPortType  port_type = MIC;

   header_type = unsupported_sound_file;
   data_format = snd_unsupported;
   data_location = 0;
   dur = 0.0;

   audio_in = 0;
   p1_is_audioport = 0;
   is_open = 0;

   /* Cast Minc double to int, then to a string ptr. */
   anint = (int) pp[0];
   sfname = (char *) anint;

   if (strcmp(sfname, "AUDIO") == 0) {
      audio_in = 1;

      if (pp[1] != 0.0) {
         p1_is_audioport = 1;
         anint = (int) pp[1];
         str = (char *) anint;
         if (strcmp(str, "MIC") == 0)
            port_type = MIC;
         else if (strcmp(str, "LINE") == 0)
            port_type = LINE;
         else if (strcmp(str, "DIGITAL") == 0)
            port_type = DIGITAL;
         else
            p1_is_audioport = 0;           /* p[1] might be a bus spec. */
      }

      /* This signals inTraverse() to grab buffers from the audio device. */
      audio_on = 1;
   }

#ifdef INPUT_BUS_SUPPORT
   /* Parse bus specification. */

   busindex = 0;
   for (i = 0; i < MAXBUS; i++)
      buslist[i] = -1;

   type = BUS_IN;
   startchan = endchan = -1;

   start_pfield = p1_is_audioport ? 2 : 1;

   for (i = start_pfield; i < n_args; i++) {
      ErrCode  err;

      anint = (int) pp[i];
      str = (char *) anint;

      err = parse_bus_name(str, &type, &startchan, &endchan);
      if (err) {
         fprintf(stderr, "rtinput: invalid bus name specification.\n");
         exit(1);       /* syntax error */
      }
      if (type != BUS_IN) {
         fprintf(stderr, "You have to use an \"in\" bus with rtinput.\n");
         exit(1);       /* syntax error */
      }
      for (j = startchan; j <= endchan; j++)
         buslist[busindex++] = j;
   }

   if (startchan == -1) {           /* no bus specified */
   }
#endif /* INPUT_BUS_SUPPORT */

   /* See if this audio device or file has already been opened. */
   for (i = 0; i < MAX_INPUT_FDS; i++) {
      if (inputFileTable[i].fd != NO_FD) {
         if (strcmp(sfname, inputFileTable[i].filename) == 0) {
            last_input_index = i;
            is_open = 1;
            break;
         }
      }
   }

   if (!is_open) {                  /* then open audio device or file. */

      if (audio_in) {
         fd = open_audio_input(port_type, nchans);
         if (fd == -1)
            return -1.0;
#ifdef INPUT_BUS_SUPPORT
#endif /* INPUT_BUS_SUPPORT */
      }
      else {
         fd = open_sound_file(sfname, &header_type, &data_format,
                                    &data_location, &srate, &nchans, &nsamps);
         if (fd == -1)
            return -1.0;

#ifdef INPUT_BUS_SUPPORT
         if (startchan == -1) {     /* no bus specified above */
            startchan = 0;
            endchan = nchans - 1;
         }
         else {
            if (endchan - startchan >= nchans) {
               fprintf(stderr, "WARNING: You specifed more input buses than "
                               "input file '%s' has channels.\n", sfname);
               fprintf(stderr, "Using in buses %d    \n", foo);
               endchan = (startchan + nchans) - 1;
            }
         }
#endif /* INPUT_BUS_SUPPORT */

         dur = (double) (nsamps / nchans) / srate;
         if (print_is_on) {
            printf("Input file set for reading:\n");
            printf("      name:  %s\n", sfname);
            printf("      type:  %s\n", sound_type_name(header_type));
            printf("    format:  %s\n", sound_format_name(data_format));
            printf("     srate:  %g\n", srate);
            printf("     chans:  %d\n", nchans);
            printf("  duration:  %g\n\n", dur);
#ifdef INPUT_BUS_SUPPORT
#endif /* INPUT_BUS_SUPPORT */
         }
         if (srate != SR) {
            fprintf(stderr, "WARNING: The input file sampling rate is %g, but "
                            "the output rate is currently %g.\n", srate, SR);
         }
      }

      /* Put new file descriptor into the first available slot in the
         inputFileTable.  Also copy the filename for later checking, and
         fill in the other fields in the InputDesc struct (see rtdefs.h).

         last_input_index is the value that will be used by any instrument
         created after this call to rtinput().
      */
      for (i = 0; i < MAX_INPUT_FDS; i++) {
         if (inputFileTable[i].fd == NO_FD) {
            inputFileTable[i].filename = strdup(sfname);
            inputFileTable[i].fd = fd;
            inputFileTable[i].refcount = 0;
            inputFileTable[i].is_audio_dev = audio_in;
            inputFileTable[i].header_type = header_type;
            inputFileTable[i].data_format = data_format;
            inputFileTable[i].data_location = data_location;
            inputFileTable[i].srate = (float) srate;
            inputFileTable[i].chans = nchans;
            inputFileTable[i].dur = dur;

            last_input_index = i;
            break;
         }
      }

      /* If this is true, we've used up all input descriptors in our array. */
      if (i == MAX_INPUT_FDS) {
         fprintf(stderr, "You have exceeded the maximum number of input "
                         "files (%d)!\n", MAX_INPUT_FDS);
         return -1.0;
      }
   }

   /* Return this to Minc, so user can pass it to functions. */
   return (double) last_input_index;
}

<commit_msg>Handle new in_port array. Set audioNCHANS.<commit_after>/* RTcmix  - Copyright (C) 2000  The RTcmix Development Team
   See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for
   the license to this software and for a DISCLAIMER OF ALL WARRANTIES.
*/

/* Originally by Brad Garton, Doug Scott, and Dave Topper.
   Reworked for v2.3 by John Gibson.
*/
#include <globals.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sndlibsupport.h>
#include <rtdefs.h>
#ifdef LINUX
   #include <fcntl.h>
#endif /* LINUX */
#ifdef SGI
   #include <dmedia/audio.h>
#endif /* SGI */

/* code that lets user specify buses for input sources */
//#define INPUT_BUS_SUPPORT

typedef enum {
   MIC,
   LINE,
   DIGITAL
} AudioPortType;

#ifdef LINUX
   #define open_audio_input open_linux_audio_input
#endif
#ifdef SGI
   #define open_audio_input open_sgi_audio_input
#endif

static last_input_index = -1;

/* ------------------------------------------------- get_last_input_index --- */
/* Called by rtsetinput to find out which file to set for the inst.
*/
int
get_last_input_index()
{
   return last_input_index;
}

#ifdef LINUX
/* ----------------------------------------------- open_linux_audio_input --- */
/* The device has already been opened in rtsetparams.
*/
static int
open_linux_audio_input()
{
#ifdef MONO_DEVICES
// FIXME: what do we return?
#else /* !MONO_DEVICES */
   if (in_port[0])
      return in_port[0];         /* global set in rtsetparams */
   else
      return -1;
#endif /* !MONO_DEVICES */
}
#endif /* LINUX */

#ifdef SGI
/* ------------------------------------------------- open_sgi_audio_input --- */
/*
   <port_type> is one of AL_INPUT_MIC, AL_INPUT_LINE, or AL_INPUT_DIGITAL.
*/
static int
open_sgi_audio_input(AudioPortType port_type, int nchans)
{
   int      port;
   long     pvbuf[4];
   long     buflen;
   ALconfig in_port_config;

   /* configure and open input audio port */
   in_port_config = ALnewconfig();
   ALsetwidth(in_port_config, AL_SAMPLE_16);

   if (nchans == 1)
      ALsetchannels(in_port_config, AL_MONO);
   else (nchans == 2)
      ALsetchannels(in_port_config, AL_STEREO);

   if (ALsetqueuesize(in_port_config, RTBUFSAMPS * 4) == -1) {
      fprintf(stderr,
              "Could not configure the input audio port queue size to %d.\n",
              RTBUFSAMPS * 4);
      return -1;
   }

   switch (port_type) {
      case LINE:
         port = AL_INPUT_LINE;
         break;
      case DIGITAL:
         port = AL_INPUT_DIGITAL;
         break;
      default:
         port = AL_INPUT_MIC;
         break;
   }

   pvbuf[0] = AL_INPUT_RATE;
   pvbuf[1] = (long) SR;
   pvbuf[2] = AL_INPUT_SOURCE;
   pvbuf[3] = port;
   buflen = 4;

   ALsetparams(AL_DEFAULT_DEVICE, pvbuf, buflen);

   /* open up thet thar audio port! */
   in_port = ALopenport("rtcmixin", "r", in_port_config);

   ALfreeconfig(in_port_config);

   if (!in_port) {
      fprintf(stderr, "Could not open input audio port.\n");
      return -1;
   }

   return AUDIO_DEVICE_ID;          /* our fake fd for SGI audio devices */
}
#endif /* SGI */

/* ------------------------------------------------------ open_sound_file --- */
static int
open_sound_file(
      char     *sfname,
      int      *header_type,
      int      *data_format,
      int      *data_location,
      double   *srate,
      int      *nchans,
      long     *nsamps)
{
   int         fd;
   struct stat sfst;

   /* See if file exists and is a regular file or link. */
   if (stat(sfname, &sfst) == -1) {
      fprintf(stderr, "%s: %s\n", sfname, strerror(errno));
      return -1;
   }
   if (!S_ISREG(sfst.st_mode) && !S_ISLNK(sfst.st_mode)) {
      fprintf(stderr, "%s is not a regular file or a link.\n", sfname);
      return -1;
   }

   /* Open the file and read its header. */
   fd = sndlib_open_read(sfname);
   if (fd == -1) {
      fprintf(stderr, "Can't read header of \"%s\" (%s)\n",
                                                  sfname, strerror(errno));
      return -1;
   }

   /* Now info is available from sndlib query functions. */

   *header_type = c_snd_header_type();

   if (NOT_A_SOUND_FILE(*header_type)) {
      fprintf(stderr, "\"%s\" is probably not a sound file\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }

   *data_format = c_snd_header_format();

   if (INVALID_DATA_FORMAT(*data_format)) {
      fprintf(stderr, "\"%s\" has invalid sound data format\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }
#ifdef NOMORE  // float input should work now -JG
   if (IS_FLOAT_FORMAT(*data_format)) {
      fprintf(stderr, "\"%s\": can't handle float input files yet.\n", sfname);
      sndlib_close(fd, 0, 0, 0, 0);
      return -1;
   }
#endif

   *data_location = c_snd_header_data_location();
   *srate = (double) c_snd_header_srate();
   *nchans = c_snd_header_chans();
   *nsamps = c_snd_header_data_size();

   return fd;
}

/* -------------------------------------------------------------- rtinput --- */
/* This function is used in the score to open a file or an audio device for
   subsequent reads by RT Instruments. "rtsetinput" is used in
   the init member functions of the Instruments to access the file.

   p[0] is either a sound file name or "AUDIO" (for an audio device).

   If it's "AUDIO", then p[1] (optional) can be "MIC", "LINE" or
   "DIGITAL". (This option not available yet under Linux.)
   This sets up the input device to do real-time reading of sound.

FIXME: this stuff not implemented yet  -JGG
   pfields after these are bus specification strings in the format
   accepted by the bus_config Minc function. They *must* be "in"
   buses, not "auxin". The bus spec. is optional - if absent, the
   default is "in0-X", where `X' is the number of channels in the
   sound file; "AUDIO" input defaults to stereo ("in0-1").

   Note that the only reason to bother with the bus specification
   is to make it possible to have more than one input source for
   an instrument.
*/
double
rtinput(float p[], int n_args, double pp[])
{
   int            i, j, anint, audio_in, p1_is_audioport, start_pfield, fd;
   int            is_open, header_type, data_format, data_location, nchans;
#ifdef INPUT_BUS_SUPPORT
   int            startchan, endchan;
   short          busindex, buslist[MAXBUS];
   BusType        type;
#endif /* INPUT_BUS_SUPPORT */
   long           nsamps;
   double         srate, dur;
   char           *sfname, *str;
   AudioPortType  port_type = MIC;

   header_type = unsupported_sound_file;
   data_format = snd_unsupported;
   data_location = 0;
   dur = 0.0;

   audio_in = 0;
   p1_is_audioport = 0;
   is_open = 0;

   /* Cast Minc double to int, then to a string ptr. */
   anint = (int) pp[0];
   sfname = (char *) anint;

   if (strcmp(sfname, "AUDIO") == 0) {
      audio_in = 1;

      if (pp[1] != 0.0) {
         p1_is_audioport = 1;
         anint = (int) pp[1];
         str = (char *) anint;
         if (strcmp(str, "MIC") == 0)
            port_type = MIC;
         else if (strcmp(str, "LINE") == 0)
            port_type = LINE;
         else if (strcmp(str, "DIGITAL") == 0)
            port_type = DIGITAL;
         else
            p1_is_audioport = 0;           /* p[1] might be a bus spec. */
      }

      /* This signals inTraverse() to grab buffers from the audio device. */
      audio_on = 1;

// FIXME: need to replace this with the bus spec scheme below... -JGG
      audioNCHANS = (n_args > 2) ? (int) p[2] : NCHANS;
   }

#ifdef INPUT_BUS_SUPPORT
   /* Parse bus specification. */

   busindex = 0;
   for (i = 0; i < MAXBUS; i++)
      buslist[i] = -1;

   type = BUS_IN;
   startchan = endchan = -1;

   start_pfield = p1_is_audioport ? 2 : 1;

   for (i = start_pfield; i < n_args; i++) {
      ErrCode  err;

      anint = (int) pp[i];
      str = (char *) anint;

      err = parse_bus_name(str, &type, &startchan, &endchan);
      if (err) {
         fprintf(stderr, "rtinput: invalid bus name specification.\n");
         exit(1);       /* syntax error */
      }
      if (type != BUS_IN) {
         fprintf(stderr, "You have to use an \"in\" bus with rtinput.\n");
         exit(1);       /* syntax error */
      }
      for (j = startchan; j <= endchan; j++)
         buslist[busindex++] = j;
   }

   if (startchan == -1) {           /* no bus specified */
   }
#endif /* INPUT_BUS_SUPPORT */

   /* See if this audio device or file has already been opened. */
   for (i = 0; i < MAX_INPUT_FDS; i++) {
      if (inputFileTable[i].fd != NO_FD) {
         if (strcmp(sfname, inputFileTable[i].filename) == 0) {
            last_input_index = i;
            is_open = 1;
            break;
         }
      }
   }

   if (!is_open) {                  /* then open audio device or file. */

      if (audio_in) {
         fd = open_audio_input(port_type, nchans);
         if (fd == -1)
            return -1.0;
#ifdef INPUT_BUS_SUPPORT
#endif /* INPUT_BUS_SUPPORT */
      }
      else {
         fd = open_sound_file(sfname, &header_type, &data_format,
                                    &data_location, &srate, &nchans, &nsamps);
         if (fd == -1)
            return -1.0;

#ifdef INPUT_BUS_SUPPORT
         if (startchan == -1) {     /* no bus specified above */
            startchan = 0;
            endchan = nchans - 1;
         }
         else {
            if (endchan - startchan >= nchans) {
               fprintf(stderr, "WARNING: You specifed more input buses than "
                               "input file '%s' has channels.\n", sfname);
               fprintf(stderr, "Using in buses %d    \n", foo);
               endchan = (startchan + nchans) - 1;
            }
         }
#endif /* INPUT_BUS_SUPPORT */

         dur = (double) (nsamps / nchans) / srate;
         if (print_is_on) {
            printf("Input file set for reading:\n");
            printf("      name:  %s\n", sfname);
            printf("      type:  %s\n", sound_type_name(header_type));
            printf("    format:  %s\n", sound_format_name(data_format));
            printf("     srate:  %g\n", srate);
            printf("     chans:  %d\n", nchans);
            printf("  duration:  %g\n\n", dur);
#ifdef INPUT_BUS_SUPPORT
#endif /* INPUT_BUS_SUPPORT */
         }
         if (srate != SR) {
            fprintf(stderr, "WARNING: The input file sampling rate is %g, but "
                            "the output rate is currently %g.\n", srate, SR);
         }
      }

      /* Put new file descriptor into the first available slot in the
         inputFileTable.  Also copy the filename for later checking, and
         fill in the other fields in the InputDesc struct (see rtdefs.h).

         last_input_index is the value that will be used by any instrument
         created after this call to rtinput().
      */
      for (i = 0; i < MAX_INPUT_FDS; i++) {
         if (inputFileTable[i].fd == NO_FD) {
            inputFileTable[i].filename = strdup(sfname);
            inputFileTable[i].fd = fd;
            inputFileTable[i].refcount = 0;
            inputFileTable[i].is_audio_dev = audio_in;
            inputFileTable[i].header_type = header_type;
            inputFileTable[i].data_format = data_format;
            inputFileTable[i].data_location = data_location;
            inputFileTable[i].srate = (float) srate;
            inputFileTable[i].chans = nchans;
            inputFileTable[i].dur = dur;

            last_input_index = i;
            break;
         }
      }

      /* If this is true, we've used up all input descriptors in our array. */
      if (i == MAX_INPUT_FDS) {
         fprintf(stderr, "You have exceeded the maximum number of input "
                         "files (%d)!\n", MAX_INPUT_FDS);
         return -1.0;
      }
   }

   /* Return this to Minc, so user can pass it to functions. */
   return (double) last_input_index;
}

<|endoftext|>


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

#ifndef QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_
#define QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_

#include <string>
#include <vector>

#include "expressions/table_generator/GeneratorFunctionHandle.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVectorsValueAccessor.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

class ColumnVector;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief Handle for the instantiated GenerateSeries function.
 */
class GenerateSeriesHandle : public GeneratorFunctionHandle {
 public:
  /**
   * @brief Constructor
   *
   * @param func_name The registered name of the GenerateSeries function.
   * @param orig_args The original constant arguments to this function
   * @param type The unified type for the arguments.
   * @param start The start value. Its type should equal unified_type.
   * @param end The end value. Its type should equal unified_type.
   * @param step The step size. Its type should equal unified_type.
   */
  GenerateSeriesHandle(const std::string &func_name,
                       const std::vector<TypedValue> &orig_args,
                       const Type &unified_type,
                       const TypedValue &start,
                       const TypedValue &end,
                       const TypedValue &step)
      : GeneratorFunctionHandle(func_name, orig_args),
        type_(unified_type),
        start_(start),
        end_(end),
        step_(step) {
  }

  int getNumberOfOutputColumns() const override {
    return 1;
  }

  std::string getOutputColumnName(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    // Use the function name as the column name.
    return getName();
  }

  const Type &getOutputColumnType(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    return type_;
  }

  void populateColumns(ColumnVectorsValueAccessor *results) const override {
    DCHECK(results != nullptr);

    // Populate the output column.
    ColumnVector *result_vec;
    switch (type_.getTypeID()) {
      case TypeID::kInt: {
        result_vec = generateColumn<int>();
        break;
      }
      case TypeID::kLong: {
        result_vec = generateColumn<std::int64_t>();
        break;
      }
      case TypeID::kFloat: {
        result_vec = generateColumn<float>();
        break;
      }
      case TypeID::kDouble: {
        result_vec = generateColumn<double>();
        break;
      }
      default:
        LOG(FATAL) << "GenerateSeries cannot handle arguments with type "
                   << type_.getName();
    }
    results->addColumn(result_vec);
  }

 private:
  template <typename T>
  ColumnVector *generateColumn() const {
    T start = start_.getLiteral<T>();
    T end = end_.getLiteral<T>();
    T step = step_.getLiteral<T>();

    DCHECK_NE(step, 0);
    std::size_t length = static_cast<std::size_t>((end - start) / step) + 1;
    DCHECK_GE(length, 0);

    NativeColumnVector *result_vec = new NativeColumnVector(type_, length);
    T value = start;
    for (std::size_t i = 0; i < length; i++) {
      result_vec->appendUntypedValue(&value);
      value += step;
    }
    return result_vec;
  }

  const Type &type_;
  const TypedValue start_;
  const TypedValue end_;
  const TypedValue step_;

  DISALLOW_COPY_AND_ASSIGN(GenerateSeriesHandle);
};

/** @} */

}  // namespace quickstep

#endif /* QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_ */
<commit_msg>fix_DCHECK_GE_type<commit_after>/**
 *   Copyright 2016 Pivotal Software, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#ifndef QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_
#define QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_

#include <string>
#include <vector>

#include "expressions/table_generator/GeneratorFunctionHandle.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVectorsValueAccessor.hpp"
#include "utility/Macros.hpp"

#include "glog/logging.h"

namespace quickstep {

class ColumnVector;

/** \addtogroup Expressions
 *  @{
 */

/**
 * @brief Handle for the instantiated GenerateSeries function.
 */
class GenerateSeriesHandle : public GeneratorFunctionHandle {
 public:
  /**
   * @brief Constructor
   *
   * @param func_name The registered name of the GenerateSeries function.
   * @param orig_args The original constant arguments to this function
   * @param type The unified type for the arguments.
   * @param start The start value. Its type should equal unified_type.
   * @param end The end value. Its type should equal unified_type.
   * @param step The step size. Its type should equal unified_type.
   */
  GenerateSeriesHandle(const std::string &func_name,
                       const std::vector<TypedValue> &orig_args,
                       const Type &unified_type,
                       const TypedValue &start,
                       const TypedValue &end,
                       const TypedValue &step)
      : GeneratorFunctionHandle(func_name, orig_args),
        type_(unified_type),
        start_(start),
        end_(end),
        step_(step) {
  }

  int getNumberOfOutputColumns() const override {
    return 1;
  }

  std::string getOutputColumnName(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    // Use the function name as the column name.
    return getName();
  }

  const Type &getOutputColumnType(int index) const override {
    if (index > 0) {
      LOG(FATAL) << "generate_series function has only 1 output column";
    }
    return type_;
  }

  void populateColumns(ColumnVectorsValueAccessor *results) const override {
    DCHECK(results != nullptr);

    // Populate the output column.
    ColumnVector *result_vec;
    switch (type_.getTypeID()) {
      case TypeID::kInt: {
        result_vec = generateColumn<int>();
        break;
      }
      case TypeID::kLong: {
        result_vec = generateColumn<std::int64_t>();
        break;
      }
      case TypeID::kFloat: {
        result_vec = generateColumn<float>();
        break;
      }
      case TypeID::kDouble: {
        result_vec = generateColumn<double>();
        break;
      }
      default:
        LOG(FATAL) << "GenerateSeries cannot handle arguments with type "
                   << type_.getName();
    }
    results->addColumn(result_vec);
  }

 private:
  template <typename T>
  ColumnVector *generateColumn() const {
    T start = start_.getLiteral<T>();
    T end = end_.getLiteral<T>();
    T step = step_.getLiteral<T>();

    DCHECK_NE(step, static_cast<T>(0));
    std::size_t length = static_cast<std::size_t>((end - start) / step) + 1;
    DCHECK_GE(length, static_cast<std::size_t>(0));

    NativeColumnVector *result_vec = new NativeColumnVector(type_, length);
    T value = start;
    for (std::size_t i = 0; i < length; i++) {
      result_vec->appendUntypedValue(&value);
      value += step;
    }
    return result_vec;
  }

  const Type &type_;
  const TypedValue start_;
  const TypedValue end_;
  const TypedValue step_;

  DISALLOW_COPY_AND_ASSIGN(GenerateSeriesHandle);
};

/** @} */

}  // namespace quickstep

#endif /* QUICKSTEP_EXPRESSIONS_TABLE_GENERATOR_GENERATE_SERIES_HANDLE_HPP_ */
<|endoftext|>


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

/**
 * @file
 **/

#include "modules/planning/lattice/trajectory1d/piecewise_trajectory1d.h"

#include <cmath>

#include "modules/common/log.h"

#include "glog/logging.h"

namespace apollo {
namespace planning {

double PiecewiseTrajectory1d::Evaluate(const std::uint32_t order,
                                       const double param) const {
  auto it_lower = std::lower_bound(accumulated_param_lengths_.begin(),
                                   accumulated_param_lengths_.end(), param);
  CHECK(it_lower != accumulated_param_lengths_.end());

  std::size_t index =
      (std::size_t)(it_lower - accumulated_param_lengths_.begin());

  double param_overhead = 0.0;
  if (index != 0) {
    param_overhead = accumulated_param_lengths_[index - 1];
  }
  return trajectory_segments_[index]->Evaluate(order, param - param_overhead);
}

double PiecewiseTrajectory1d::ParamLength() const {
  if (accumulated_param_lengths_.empty()) {
    return 0.0;
  }
  return accumulated_param_lengths_.back();
}

std::string PiecewiseTrajectory1d::ToString() const { return ""; }

void PiecewiseTrajectory1d::AppendSegment(
    const std::shared_ptr<Curve1d> trajectory) {
  if (trajectory_segments_.size() > 0) {
    trajectory_segments_.push_back(trajectory);
  } else {
    double s1 = trajectory->Evaluate(0, 0.0);
    double v1 = trajectory->Evaluate(1, 0.0);
    double a1 = trajectory->Evaluate(2, 0.0);
    double j1 = trajectory->Evaluate(3, 0.0);

    auto last_trajectory = trajectory_segments_.back();
    double last_param_length = last_trajectory->ParamLength();
    double s0 = last_trajectory->Evaluate(0, last_param_length);
    double v0 = last_trajectory->Evaluate(1, last_param_length);
    double a0 = last_trajectory->Evaluate(2, last_param_length);
    double j0 = last_trajectory->Evaluate(3, last_param_length);

    if (std::fabs(s0 - s1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 0";
    }

    if (std::fabs(v0 - v1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 1";
    }

    if (std::fabs(a0 - a1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 2";
    }

    if (std::fabs(j0 - j1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 3";
    }
    trajectory_segments_.push_back(trajectory);
  }

  double accumulated_param_length = trajectory->ParamLength();
  if (accumulated_param_lengths_.size() > 0) {
    accumulated_param_length += accumulated_param_lengths_.back();
  }
  accumulated_param_lengths_.push_back(accumulated_param_length);
}

void PiecewiseTrajectory1d::PopSegment() {
  if (trajectory_segments_.empty()) {
    return;
  }
  trajectory_segments_.pop_back();
  accumulated_param_lengths_.pop_back();
}

std::size_t PiecewiseTrajectory1d::NumOfSegments() const {
  return trajectory_segments_.size();
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: bug fix in piecewise_trajectory1d<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/trajectory1d/piecewise_trajectory1d.h"

#include <cmath>

#include "modules/common/log.h"

#include "glog/logging.h"

namespace apollo {
namespace planning {

double PiecewiseTrajectory1d::Evaluate(const std::uint32_t order,
                                       const double param) const {
  auto it_lower = std::lower_bound(accumulated_param_lengths_.begin(),
                                   accumulated_param_lengths_.end(), param);
  CHECK(it_lower != accumulated_param_lengths_.end());

  std::size_t index =
      (std::size_t)(it_lower - accumulated_param_lengths_.begin());

  double param_overhead = 0.0;
  if (index != 0) {
    param_overhead = accumulated_param_lengths_[index - 1];
  }
  return trajectory_segments_[index]->Evaluate(order, param - param_overhead);
}

double PiecewiseTrajectory1d::ParamLength() const {
  if (accumulated_param_lengths_.empty()) {
    return 0.0;
  }
  return accumulated_param_lengths_.back();
}

std::string PiecewiseTrajectory1d::ToString() const { return ""; }

void PiecewiseTrajectory1d::AppendSegment(
    const std::shared_ptr<Curve1d> trajectory) {
  if (trajectory_segments_.size() == 0) {
    trajectory_segments_.push_back(trajectory);
  } else {
    double s1 = trajectory->Evaluate(0, 0.0);
    double v1 = trajectory->Evaluate(1, 0.0);
    double a1 = trajectory->Evaluate(2, 0.0);
    double j1 = trajectory->Evaluate(3, 0.0);

    auto last_trajectory = trajectory_segments_.back();
    double last_param_length = last_trajectory->ParamLength();
    double s0 = last_trajectory->Evaluate(0, last_param_length);
    double v0 = last_trajectory->Evaluate(1, last_param_length);
    double a0 = last_trajectory->Evaluate(2, last_param_length);
    double j0 = last_trajectory->Evaluate(3, last_param_length);

    if (std::fabs(s0 - s1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 0";
    }

    if (std::fabs(v0 - v1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 1";
    }

    if (std::fabs(a0 - a1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 2";
    }

    if (std::fabs(j0 - j1) > 1.0e-4) {
      AWARN << "The appended segment is not smooth in order 3";
    }
    trajectory_segments_.push_back(trajectory);
  }

  double accumulated_param_length = trajectory->ParamLength();
  if (accumulated_param_lengths_.size() > 0) {
    accumulated_param_length += accumulated_param_lengths_.back();
  }
  accumulated_param_lengths_.push_back(accumulated_param_length);
}

void PiecewiseTrajectory1d::PopSegment() {
  if (trajectory_segments_.empty()) {
    return;
  }
  trajectory_segments_.pop_back();
  accumulated_param_lengths_.pop_back();
}

std::size_t PiecewiseTrajectory1d::NumOfSegments() const {
  return trajectory_segments_.size();
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>