<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

//Poco headers
#include <Poco/Zip/Compress.h>
#include <Poco/Path.h>

//mitk headers
#include "mitkNavigationToolWriter.h"
#include <mitkStandaloneDataStorage.h>
#include <mitkProperties.h>
#include <mitkSceneIO.h>
#include <mitkPointSet.h>
#include <mitkIOUtil.h>

//std headers
#include <cstdio>

mitk::NavigationToolWriter::NavigationToolWriter()
  {

  }

mitk::NavigationToolWriter::~NavigationToolWriter()
  {

  }

bool mitk::NavigationToolWriter::DoWrite(std::string FileName,mitk::NavigationTool::Pointer Tool)
  {
  //some initial validation checks...
  if ( Tool.IsNull())
    {
    m_ErrorMessage = "Cannot write a navigation tool containing invalid tool data, aborting!";
    MITK_ERROR << m_ErrorMessage;
    return false;
    }

  // Workaround for a problem: the geometry might be modified if the tool is tracked. If this
  // modified geometry is saved the surface representation is moved by this offset. To avoid
  // this bug, the geometry is set to identity for the saving progress and restored later.
  mitk::BaseGeometry::Pointer geometryBackup;
  if (  Tool->GetDataNode().IsNotNull()
        && (Tool->GetDataNode()->GetData()!=nullptr)
        && (Tool->GetDataNode()->GetData()->GetGeometry()!=nullptr)
        )
      {
      geometryBackup = Tool->GetDataNode()->GetData()->GetGeometry()->Clone();
      Tool->GetDataNode()->GetData()->GetGeometry()->SetIdentity();
      }
  else {MITK_WARN << "Saving a tool with invalid data node, proceeding but errors might occure!";}

  //convert whole data to a mitk::DataStorage
  mitk::StandaloneDataStorage::Pointer saveStorage = mitk::StandaloneDataStorage::New();
  mitk::DataNode::Pointer thisTool = ConvertToDataNode(Tool);
  saveStorage->Add(thisTool);

  //use SceneSerialization to save the DataStorage
  std::string DataStorageFileName = mitk::IOUtil::CreateTemporaryDirectory() + Poco::Path::separator() + GetFileWithoutPath(FileName) + ".storage";
  mitk::SceneIO::Pointer mySceneIO = mitk::SceneIO::New();
  mySceneIO->SaveScene(saveStorage->GetAll(),saveStorage,DataStorageFileName);

  //now put the DataStorage and the Toolfile in a ZIP-file
  std::ofstream file( FileName.c_str(), std::ios::binary | std::ios::out);
  if (!file.good())
    {
    m_ErrorMessage = "Could not open a zip file for writing: '" + FileName + "'";
    MITK_ERROR << m_ErrorMessage;
    return false;
    }
  else
    {
    Poco::Zip::Compress zipper( file, true );
    zipper.addFile(DataStorageFileName,GetFileWithoutPath(DataStorageFileName));
    if (Tool->GetCalibrationFile()!="none") zipper.addFile(Tool->GetCalibrationFile(),GetFileWithoutPath(Tool->GetCalibrationFile()));
    zipper.close();
    }

  //delete the data storage
  std::remove(DataStorageFileName.c_str());

  //restore original geometry
  if (geometryBackup.IsNotNull()) {Tool->GetDataNode()->GetData()->SetGeometry(geometryBackup);}

  return true;
  }

mitk::DataNode::Pointer mitk::NavigationToolWriter::ConvertToDataNode(mitk::NavigationTool::Pointer Tool)
  {
    mitk::DataNode::Pointer thisTool = Tool->GetDataNode();
  //Name
    if (Tool->GetDataNode().IsNull())
    {
      thisTool = mitk::DataNode::New();
      thisTool->SetName("none");
    }

  //Identifier
    thisTool->AddProperty("identifier",mitk::StringProperty::New(Tool->GetIdentifier().c_str()));
  //Serial Number
    thisTool->AddProperty("serial number",mitk::StringProperty::New(Tool->GetSerialNumber().c_str()));
  //Tracking Device
    thisTool->AddProperty("tracking device type",mitk::StringProperty::New(Tool->GetTrackingDeviceType()));
  //Tool Type
    thisTool->AddProperty("tracking tool type",mitk::IntProperty::New(Tool->GetType()));
  //Calibration File Name
    thisTool->AddProperty("toolfileName",mitk::StringProperty::New(GetFileWithoutPath(Tool->GetCalibrationFile())));
  //Tool Landmarks
    thisTool->AddProperty("ToolRegistrationLandmarks",mitk::StringProperty::New(ConvertPointSetToString(Tool->GetToolLandmarks())));
    thisTool->AddProperty("ToolCalibrationLandmarks",mitk::StringProperty::New(ConvertPointSetToString(Tool->GetToolControlPoints())));

  //Tool Tip
    if (Tool->IsToolTipSet())
    {
      thisTool->AddProperty("ToolTipPosition",mitk::StringProperty::New(ConvertPointToString(Tool->GetToolTipPosition())));
      thisTool->AddProperty("ToolAxisOrientation",mitk::StringProperty::New(ConvertQuaternionToString(Tool->GetToolAxisOrientation())));
    }

  //Tool Axis
    thisTool->AddProperty("ToolAxis", mitk::StringProperty::New(ConvertPointToString(Tool->GetToolAxis())));

  //Material is not needed, to avoid errors in scene serialization we have to do this:
    thisTool->RemoveProperty("material");

  return thisTool;
  }

std::string mitk::NavigationToolWriter::GetFileWithoutPath(std::string FileWithPath)
  {
  Poco::Path myFile(FileWithPath.c_str());
  return myFile.getFileName();
  }

std::string mitk::NavigationToolWriter::ConvertPointSetToString(mitk::PointSet::Pointer pointSet)
  {
  std::stringstream returnValue;
  mitk::PointSet::PointDataIterator it;
  for ( it = pointSet->GetPointSet()->GetPointData()->Begin();it != pointSet->GetPointSet()->GetPointData()->End();it++ )
    {
    mitk::Point3D thisPoint = pointSet->GetPoint(it->Index());
    returnValue << it->Index() << ";" << ConvertPointToString(thisPoint) << "|";
    }
  return returnValue.str();
  }

std::string mitk::NavigationToolWriter::ConvertPointToString(mitk::Point3D point)
{
std::stringstream returnValue;
returnValue << point[0] << ";" << point[1] << ";" << point[2];
return returnValue.str();
}

std::string mitk::NavigationToolWriter::ConvertQuaternionToString(mitk::Quaternion quat)
{
std::stringstream returnValue;
returnValue << quat.x() << ";" << quat.y() << ";" << quat.z() << ";" << quat.r();
return returnValue.str();
}
<commit_msg>Overwrite properties if they already exist<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

//Poco headers
#include <Poco/Zip/Compress.h>
#include <Poco/Path.h>

//mitk headers
#include "mitkNavigationToolWriter.h"
#include <mitkStandaloneDataStorage.h>
#include <mitkProperties.h>
#include <mitkSceneIO.h>
#include <mitkPointSet.h>
#include <mitkIOUtil.h>

//std headers
#include <cstdio>

mitk::NavigationToolWriter::NavigationToolWriter()
  {

  }

mitk::NavigationToolWriter::~NavigationToolWriter()
  {

  }

bool mitk::NavigationToolWriter::DoWrite(std::string FileName,mitk::NavigationTool::Pointer Tool)
  {
  //some initial validation checks...
  if ( Tool.IsNull())
    {
    m_ErrorMessage = "Cannot write a navigation tool containing invalid tool data, aborting!";
    MITK_ERROR << m_ErrorMessage;
    return false;
    }

  // Workaround for a problem: the geometry might be modified if the tool is tracked. If this
  // modified geometry is saved the surface representation is moved by this offset. To avoid
  // this bug, the geometry is set to identity for the saving progress and restored later.
  mitk::BaseGeometry::Pointer geometryBackup;
  if (  Tool->GetDataNode().IsNotNull()
        && (Tool->GetDataNode()->GetData()!=nullptr)
        && (Tool->GetDataNode()->GetData()->GetGeometry()!=nullptr)
        )
      {
      geometryBackup = Tool->GetDataNode()->GetData()->GetGeometry()->Clone();
      Tool->GetDataNode()->GetData()->GetGeometry()->SetIdentity();
      }
  else {MITK_WARN << "Saving a tool with invalid data node, proceeding but errors might occure!";}

  //convert whole data to a mitk::DataStorage
  mitk::StandaloneDataStorage::Pointer saveStorage = mitk::StandaloneDataStorage::New();
  mitk::DataNode::Pointer thisTool = ConvertToDataNode(Tool);
  saveStorage->Add(thisTool);

  //use SceneSerialization to save the DataStorage
  std::string DataStorageFileName = mitk::IOUtil::CreateTemporaryDirectory() + Poco::Path::separator() + GetFileWithoutPath(FileName) + ".storage";
  mitk::SceneIO::Pointer mySceneIO = mitk::SceneIO::New();
  mySceneIO->SaveScene(saveStorage->GetAll(),saveStorage,DataStorageFileName);

  //now put the DataStorage and the Toolfile in a ZIP-file
  std::ofstream file( FileName.c_str(), std::ios::binary | std::ios::out);
  if (!file.good())
    {
    m_ErrorMessage = "Could not open a zip file for writing: '" + FileName + "'";
    MITK_ERROR << m_ErrorMessage;
    return false;
    }
  else
    {
    Poco::Zip::Compress zipper( file, true );
    zipper.addFile(DataStorageFileName,GetFileWithoutPath(DataStorageFileName));
    if (Tool->GetCalibrationFile()!="none") zipper.addFile(Tool->GetCalibrationFile(),GetFileWithoutPath(Tool->GetCalibrationFile()));
    zipper.close();
    }

  //delete the data storage
  std::remove(DataStorageFileName.c_str());

  //restore original geometry
  if (geometryBackup.IsNotNull()) {Tool->GetDataNode()->GetData()->SetGeometry(geometryBackup);}

  return true;
  }

mitk::DataNode::Pointer mitk::NavigationToolWriter::ConvertToDataNode(mitk::NavigationTool::Pointer Tool)
  {
    mitk::DataNode::Pointer thisTool = Tool->GetDataNode();
  //Name
    if (Tool->GetDataNode().IsNull())
    {
      thisTool = mitk::DataNode::New();
      thisTool->SetName("none");
    }

  //Identifier
    thisTool->AddProperty("identifier",mitk::StringProperty::New(Tool->GetIdentifier().c_str()), NULL, true);
  //Serial Number
    thisTool->AddProperty("serial number",mitk::StringProperty::New(Tool->GetSerialNumber().c_str()), NULL, true);
  //Tracking Device
    thisTool->AddProperty("tracking device type",mitk::StringProperty::New(Tool->GetTrackingDeviceType()), NULL, true);
  //Tool Type
    thisTool->AddProperty("tracking tool type",mitk::IntProperty::New(Tool->GetType()), NULL, true);
  //Calibration File Name
    thisTool->AddProperty("toolfileName",mitk::StringProperty::New(GetFileWithoutPath(Tool->GetCalibrationFile())), NULL, true);
  //Tool Landmarks
    thisTool->AddProperty("ToolRegistrationLandmarks",mitk::StringProperty::New(ConvertPointSetToString(Tool->GetToolLandmarks())), NULL, true);
    thisTool->AddProperty("ToolCalibrationLandmarks",mitk::StringProperty::New(ConvertPointSetToString(Tool->GetToolControlPoints())), NULL, true);

  //Tool Tip
    if (Tool->IsToolTipSet())
    {
      thisTool->AddProperty("ToolTipPosition",mitk::StringProperty::New(ConvertPointToString(Tool->GetToolTipPosition())), NULL, true);
      thisTool->AddProperty("ToolAxisOrientation",mitk::StringProperty::New(ConvertQuaternionToString(Tool->GetToolAxisOrientation())), NULL, true);
    }

  //Tool Axis
    thisTool->AddProperty("ToolAxis", mitk::StringProperty::New(ConvertPointToString(Tool->GetToolAxis())),NULL,true);

  //Material is not needed, to avoid errors in scene serialization we have to do this:
    thisTool->RemoveProperty("material");

  return thisTool;
  }

std::string mitk::NavigationToolWriter::GetFileWithoutPath(std::string FileWithPath)
  {
  Poco::Path myFile(FileWithPath.c_str());
  return myFile.getFileName();
  }

std::string mitk::NavigationToolWriter::ConvertPointSetToString(mitk::PointSet::Pointer pointSet)
  {
  std::stringstream returnValue;
  mitk::PointSet::PointDataIterator it;
  for ( it = pointSet->GetPointSet()->GetPointData()->Begin();it != pointSet->GetPointSet()->GetPointData()->End();it++ )
    {
    mitk::Point3D thisPoint = pointSet->GetPoint(it->Index());
    returnValue << it->Index() << ";" << ConvertPointToString(thisPoint) << "|";
    }
  return returnValue.str();
  }

std::string mitk::NavigationToolWriter::ConvertPointToString(mitk::Point3D point)
{
std::stringstream returnValue;
returnValue << point[0] << ";" << point[1] << ";" << point[2];
return returnValue.str();
}

std::string mitk::NavigationToolWriter::ConvertQuaternionToString(mitk::Quaternion quat)
{
std::stringstream returnValue;
returnValue << quat.x() << ";" << quat.y() << ";" << quat.z() << ";" << quat.r();
return returnValue.str();
}
<|endoftext|>


<commit_before>/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Glob.hxx)

#include KWSYS_HEADER(Configure.hxx)

#include KWSYS_HEADER(RegularExpression.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
#include KWSYS_HEADER(stl/string)
#include KWSYS_HEADER(stl/vector)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Glob.hxx.in"
# include "Directory.hxx.in"
# include "Configure.hxx.in"
# include "RegularExpression.hxx.in"
# include "SystemTools.hxx.in"
# include "kwsys_stl.hxx.in"
# include "kwsys_stl_string.hxx.in"
#endif

#include <ctype.h>
#include <stdio.h>
#include <string.h>
namespace KWSYS_NAMESPACE
{
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
// On Windows and apple, no difference between lower and upper case
# define KWSYS_GLOB_CASE_INDEPENDENT
#endif

#if defined(_WIN32) || defined(__CYGWIN__)
// Handle network paths
# define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
#endif

//----------------------------------------------------------------------------
class GlobInternals
{
public:
  kwsys_stl::vector<kwsys_stl::string> Files;
  kwsys_stl::vector<kwsys::RegularExpression> Expressions;
};

//----------------------------------------------------------------------------
Glob::Glob()
{
  this->Internals = new GlobInternals;
  this->Recurse = false;
  this->Relative = "";

  this->RecurseThroughSymlinks = true;
    // RecurseThroughSymlinks is true by default for backwards compatibility,
    // not because it's a good idea...
  this->FollowedSymlinkCount = 0;
}

//----------------------------------------------------------------------------
Glob::~Glob()
{
  delete this->Internals;
}

//----------------------------------------------------------------------------
kwsys_stl::vector<kwsys_stl::string>& Glob::GetFiles()
{
  return this->Internals->Files;
}

//----------------------------------------------------------------------------
kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
                                       bool require_whole_string,
                                       bool preserve_case)
{
  // Incrementally build the regular expression from the pattern.
  kwsys_stl::string regex = require_whole_string? "^" : "";
  kwsys_stl::string::const_iterator pattern_first = pattern.begin();
  kwsys_stl::string::const_iterator pattern_last = pattern.end();
  for(kwsys_stl::string::const_iterator i = pattern_first;
      i != pattern_last; ++i)
    {
    int c = *i;
    if(c == '*')
      {
      // A '*' (not between brackets) matches any string.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]*";
      }
    else if(c == '?')
      {
      // A '?' (not between brackets) matches any single character.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]";
      }
    else if(c == '[')
      {
      // Parse out the bracket expression.  It begins just after the
      // opening character.
      kwsys_stl::string::const_iterator bracket_first = i+1;
      kwsys_stl::string::const_iterator bracket_last = bracket_first;

      // The first character may be complementation '!' or '^'.
      if(bracket_last != pattern_last &&
         (*bracket_last == '!' || *bracket_last == '^'))
        {
        ++bracket_last;
        }

      // If the next character is a ']' it is included in the brackets
      // because the bracket string may not be empty.
      if(bracket_last != pattern_last && *bracket_last == ']')
        {
        ++bracket_last;
        }

      // Search for the closing ']'.
      while(bracket_last != pattern_last && *bracket_last != ']')
        {
        ++bracket_last;
        }

      // Check whether we have a complete bracket string.
      if(bracket_last == pattern_last)
        {
        // The bracket string did not end, so it was opened simply by
        // a '[' that is supposed to be matched literally.
        regex += "\\[";
        }
      else
        {
        // Convert the bracket string to its regex equivalent.
        kwsys_stl::string::const_iterator k = bracket_first;

        // Open the regex block.
        regex += "[";

        // A regex range complement uses '^' instead of '!'.
        if(k != bracket_last && *k == '!')
          {
          regex += "^";
          ++k;
          }

        // Convert the remaining characters.
        for(; k != bracket_last; ++k)
          {
          // Backslashes must be escaped.
          if(*k == '\\')
            {
            regex += "\\";
            }

          // Store this character.
          regex += *k;
          }

        // Close the regex block.
        regex += "]";

        // Jump to the end of the bracket string.
        i = bracket_last;
        }
      }
    else
      {
      // A single character matches itself.
      int ch = c;
      if(!(('a' <= ch && ch <= 'z') ||
           ('A' <= ch && ch <= 'Z') ||
           ('0' <= ch && ch <= '9')))
        {
        // Escape the non-alphanumeric character.
        regex += "\\";
        }
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
      else
        {
        // On case-insensitive systems file names are converted to lower
        // case before matching.
        if(!preserve_case)
          {
          ch = tolower(ch);
          }
        }
#endif
      (void)preserve_case;
      // Store the character.
      regex.append(1, static_cast<char>(ch));
      }
    }

  if(require_whole_string)
    {
    regex += "$";
    }
  return regex;
}

//----------------------------------------------------------------------------
void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
  const kwsys_stl::string& dir)
{
  kwsys::Directory d;
  if ( !d.Load(dir.c_str()) )
    {
    return;
    }
  unsigned long cc;
  kwsys_stl::string fullname;
  kwsys_stl::string realname;
  kwsys_stl::string fname;
  for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
    {
    fname = d.GetFile(cc);
    if ( strcmp(fname.c_str(), ".") == 0 ||
      strcmp(fname.c_str(), "..") == 0  )
      {
      continue;
      }

    if ( start == 0 )
      {
      realname = dir + fname;
      }
    else
      {
      realname = dir + "/" + fname;
      }

#if defined( KWSYS_GLOB_CASE_INDEPENDENT )
    // On Windows and apple, no difference between lower and upper case
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    if ( start == 0 )
      {
      fullname = dir + fname;
      }
    else
      {
      fullname = dir + "/" + fname;
      }

    bool isDir = kwsys::SystemTools::FileIsDirectory(realname.c_str());

    if ( !isDir )
      {
      if ( (this->Internals->Expressions.size() > 0) &&
           this->Internals->Expressions[
             this->Internals->Expressions.size()-1].find(fname.c_str()) )
        {
        this->AddFile(this->Internals->Files, realname.c_str());
        }
      }
    else
      {
      bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname.c_str());
      if (!isSymLink || this->RecurseThroughSymlinks)
        {
        if (isSymLink)
          {
          ++this->FollowedSymlinkCount;
          }
        this->RecurseDirectory(start+1, realname);
        }
      }
    }
}

//----------------------------------------------------------------------------
void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
  const kwsys_stl::string& dir)
{
  //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl;
  bool last = ( start == this->Internals->Expressions.size()-1 );
  if ( last && this->Recurse )
    {
    this->RecurseDirectory(start, dir);
    return;
    }

  if ( start >= this->Internals->Expressions.size() )
    {
    return;
    }

  kwsys::Directory d;
  if ( !d.Load(dir.c_str()) )
    {
    return;
    }
  unsigned long cc;
  kwsys_stl::string fullname;
  kwsys_stl::string realname;
  kwsys_stl::string fname;
  for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
    {
    fname = d.GetFile(cc);
    if ( strcmp(fname.c_str(), ".") == 0 ||
      strcmp(fname.c_str(), "..") == 0  )
      {
      continue;
      }

    if ( start == 0 )
      {
      realname = dir + fname;
      }
    else
      {
      realname = dir + "/" + fname;
      }

#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
    // On case-insensitive file systems convert to lower case for matching.
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    if ( start == 0 )
      {
      fullname = dir + fname;
      }
    else
      {
      fullname = dir + "/" + fname;
      }

    //kwsys_ios::cout << "Look at file: " << fname << kwsys_ios::endl;
    //kwsys_ios::cout << "Match: "
    // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl;
    //kwsys_ios::cout << "Full name: " << fullname << kwsys_ios::endl;

    if ( !last &&
      !kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
      {
      continue;
      }

    if ( this->Internals->Expressions[start].find(fname.c_str()) )
      {
      if ( last )
        {
        this->AddFile(this->Internals->Files, realname.c_str());
        }
      else
        {
        this->ProcessDirectory(start+1, realname + "/");
        }
      }
    }
}

//----------------------------------------------------------------------------
bool Glob::FindFiles(const kwsys_stl::string& inexpr)
{
  kwsys_stl::string cexpr;
  kwsys_stl::string::size_type cc;
  kwsys_stl::string expr = inexpr;

  this->Internals->Expressions.clear();
  this->Internals->Files.clear();

  if ( !kwsys::SystemTools::FileIsFullPath(expr.c_str()) )
    {
    expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
    expr += "/" + inexpr;
    }
  kwsys_stl::string fexpr = expr;

  kwsys_stl::string::size_type skip = 0;
  kwsys_stl::string::size_type last_slash = 0;
  for ( cc = 0; cc < expr.size(); cc ++ )
    {
    if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
      {
      last_slash = cc;
      }
    if ( cc > 0 &&
      (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
      expr[cc-1] != '\\' )
      {
      break;
      }
    }
  if ( last_slash > 0 )
    {
    //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
    //<< kwsys_ios::endl;
    skip = last_slash;
    }
  if ( skip == 0 )
    {
#if defined( KWSYS_GLOB_SUPPORT_NETWORK_PATHS )
    // Handle network paths
    if ( expr[0] == '/' && expr[1] == '/' )
      {
      int cnt = 0;
      for ( cc = 2; cc < expr.size(); cc ++ )
        {
        if ( expr[cc] == '/' )
          {
          cnt ++;
          if ( cnt == 2 )
            {
            break;
            }
          }
        }
      skip = int(cc + 1);
      }
    else
#endif
      // Handle drive letters on Windows
      if ( expr[1] == ':' && expr[0] != '/' )
        {
        skip = 2;
        }
    }

  if ( skip > 0 )
    {
    expr = expr.substr(skip);
    }

  cexpr = "";
  for ( cc = 0; cc < expr.size(); cc ++ )
    {
    int ch = expr[cc];
    if ( ch == '/' )
      {
      if ( cexpr.size() > 0 )
        {
        this->AddExpression(cexpr.c_str());
        }
      cexpr = "";
      }
    else
      {
      cexpr.append(1, static_cast<char>(ch));
      }
    }
  if ( cexpr.size() > 0 )
    {
    this->AddExpression(cexpr.c_str());
    }

  // Handle network paths
  if ( skip > 0 )
    {
    this->ProcessDirectory(0, fexpr.substr(0, skip) + "/");
    }
  else
    {
    this->ProcessDirectory(0, "/");
    }
  return true;
}

//----------------------------------------------------------------------------
void Glob::AddExpression(const char* expr)
{
  this->Internals->Expressions.push_back(
    kwsys::RegularExpression(
      this->PatternToRegex(expr).c_str()));
}

//----------------------------------------------------------------------------
void Glob::SetRelative(const char* dir)
{
  if ( !dir )
    {
    this->Relative = "";
    return;
    }
  this->Relative = dir;
}

//----------------------------------------------------------------------------
const char* Glob::GetRelative()
{
  if ( this->Relative.empty() )
    {
    return 0;
    }
  return this->Relative.c_str();
}

//----------------------------------------------------------------------------
void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file)
{
  if ( !this->Relative.empty() )
    {
    files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file));
    }
  else
    {
    files.push_back(file);
    }
}

} // namespace KWSYS_NAMESPACE

<commit_msg>KWSys: Add symlinks to directories as files (#12284)<commit_after>/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "kwsysPrivate.h"
#include KWSYS_HEADER(Glob.hxx)

#include KWSYS_HEADER(Configure.hxx)

#include KWSYS_HEADER(RegularExpression.hxx)
#include KWSYS_HEADER(SystemTools.hxx)
#include KWSYS_HEADER(Directory.hxx)
#include KWSYS_HEADER(stl/string)
#include KWSYS_HEADER(stl/vector)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Glob.hxx.in"
# include "Directory.hxx.in"
# include "Configure.hxx.in"
# include "RegularExpression.hxx.in"
# include "SystemTools.hxx.in"
# include "kwsys_stl.hxx.in"
# include "kwsys_stl_string.hxx.in"
#endif

#include <ctype.h>
#include <stdio.h>
#include <string.h>
namespace KWSYS_NAMESPACE
{
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
// On Windows and apple, no difference between lower and upper case
# define KWSYS_GLOB_CASE_INDEPENDENT
#endif

#if defined(_WIN32) || defined(__CYGWIN__)
// Handle network paths
# define KWSYS_GLOB_SUPPORT_NETWORK_PATHS
#endif

//----------------------------------------------------------------------------
class GlobInternals
{
public:
  kwsys_stl::vector<kwsys_stl::string> Files;
  kwsys_stl::vector<kwsys::RegularExpression> Expressions;
};

//----------------------------------------------------------------------------
Glob::Glob()
{
  this->Internals = new GlobInternals;
  this->Recurse = false;
  this->Relative = "";

  this->RecurseThroughSymlinks = true;
    // RecurseThroughSymlinks is true by default for backwards compatibility,
    // not because it's a good idea...
  this->FollowedSymlinkCount = 0;
}

//----------------------------------------------------------------------------
Glob::~Glob()
{
  delete this->Internals;
}

//----------------------------------------------------------------------------
kwsys_stl::vector<kwsys_stl::string>& Glob::GetFiles()
{
  return this->Internals->Files;
}

//----------------------------------------------------------------------------
kwsys_stl::string Glob::PatternToRegex(const kwsys_stl::string& pattern,
                                       bool require_whole_string,
                                       bool preserve_case)
{
  // Incrementally build the regular expression from the pattern.
  kwsys_stl::string regex = require_whole_string? "^" : "";
  kwsys_stl::string::const_iterator pattern_first = pattern.begin();
  kwsys_stl::string::const_iterator pattern_last = pattern.end();
  for(kwsys_stl::string::const_iterator i = pattern_first;
      i != pattern_last; ++i)
    {
    int c = *i;
    if(c == '*')
      {
      // A '*' (not between brackets) matches any string.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]*";
      }
    else if(c == '?')
      {
      // A '?' (not between brackets) matches any single character.
      // We modify this to not match slashes since the orignal glob
      // pattern documentation was meant for matching file name
      // components separated by slashes.
      regex += "[^/]";
      }
    else if(c == '[')
      {
      // Parse out the bracket expression.  It begins just after the
      // opening character.
      kwsys_stl::string::const_iterator bracket_first = i+1;
      kwsys_stl::string::const_iterator bracket_last = bracket_first;

      // The first character may be complementation '!' or '^'.
      if(bracket_last != pattern_last &&
         (*bracket_last == '!' || *bracket_last == '^'))
        {
        ++bracket_last;
        }

      // If the next character is a ']' it is included in the brackets
      // because the bracket string may not be empty.
      if(bracket_last != pattern_last && *bracket_last == ']')
        {
        ++bracket_last;
        }

      // Search for the closing ']'.
      while(bracket_last != pattern_last && *bracket_last != ']')
        {
        ++bracket_last;
        }

      // Check whether we have a complete bracket string.
      if(bracket_last == pattern_last)
        {
        // The bracket string did not end, so it was opened simply by
        // a '[' that is supposed to be matched literally.
        regex += "\\[";
        }
      else
        {
        // Convert the bracket string to its regex equivalent.
        kwsys_stl::string::const_iterator k = bracket_first;

        // Open the regex block.
        regex += "[";

        // A regex range complement uses '^' instead of '!'.
        if(k != bracket_last && *k == '!')
          {
          regex += "^";
          ++k;
          }

        // Convert the remaining characters.
        for(; k != bracket_last; ++k)
          {
          // Backslashes must be escaped.
          if(*k == '\\')
            {
            regex += "\\";
            }

          // Store this character.
          regex += *k;
          }

        // Close the regex block.
        regex += "]";

        // Jump to the end of the bracket string.
        i = bracket_last;
        }
      }
    else
      {
      // A single character matches itself.
      int ch = c;
      if(!(('a' <= ch && ch <= 'z') ||
           ('A' <= ch && ch <= 'Z') ||
           ('0' <= ch && ch <= '9')))
        {
        // Escape the non-alphanumeric character.
        regex += "\\";
        }
#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
      else
        {
        // On case-insensitive systems file names are converted to lower
        // case before matching.
        if(!preserve_case)
          {
          ch = tolower(ch);
          }
        }
#endif
      (void)preserve_case;
      // Store the character.
      regex.append(1, static_cast<char>(ch));
      }
    }

  if(require_whole_string)
    {
    regex += "$";
    }
  return regex;
}

//----------------------------------------------------------------------------
void Glob::RecurseDirectory(kwsys_stl::string::size_type start,
  const kwsys_stl::string& dir)
{
  kwsys::Directory d;
  if ( !d.Load(dir.c_str()) )
    {
    return;
    }
  unsigned long cc;
  kwsys_stl::string fullname;
  kwsys_stl::string realname;
  kwsys_stl::string fname;
  for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
    {
    fname = d.GetFile(cc);
    if ( strcmp(fname.c_str(), ".") == 0 ||
      strcmp(fname.c_str(), "..") == 0  )
      {
      continue;
      }

    if ( start == 0 )
      {
      realname = dir + fname;
      }
    else
      {
      realname = dir + "/" + fname;
      }

#if defined( KWSYS_GLOB_CASE_INDEPENDENT )
    // On Windows and apple, no difference between lower and upper case
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    if ( start == 0 )
      {
      fullname = dir + fname;
      }
    else
      {
      fullname = dir + "/" + fname;
      }

    bool isDir = kwsys::SystemTools::FileIsDirectory(realname.c_str());
    bool isSymLink = kwsys::SystemTools::FileIsSymlink(realname.c_str());

    if ( isDir && (!isSymLink || this->RecurseThroughSymlinks) )
      {
      if (isSymLink)
        {
        ++this->FollowedSymlinkCount;
        }
      this->RecurseDirectory(start+1, realname);
      }
    else
      {
      if ( (this->Internals->Expressions.size() > 0) &&
           this->Internals->Expressions[
             this->Internals->Expressions.size()-1].find(fname.c_str()) )
        {
        this->AddFile(this->Internals->Files, realname.c_str());
        }
      }
    }
}

//----------------------------------------------------------------------------
void Glob::ProcessDirectory(kwsys_stl::string::size_type start,
  const kwsys_stl::string& dir)
{
  //kwsys_ios::cout << "ProcessDirectory: " << dir << kwsys_ios::endl;
  bool last = ( start == this->Internals->Expressions.size()-1 );
  if ( last && this->Recurse )
    {
    this->RecurseDirectory(start, dir);
    return;
    }

  if ( start >= this->Internals->Expressions.size() )
    {
    return;
    }

  kwsys::Directory d;
  if ( !d.Load(dir.c_str()) )
    {
    return;
    }
  unsigned long cc;
  kwsys_stl::string fullname;
  kwsys_stl::string realname;
  kwsys_stl::string fname;
  for ( cc = 0; cc < d.GetNumberOfFiles(); cc ++ )
    {
    fname = d.GetFile(cc);
    if ( strcmp(fname.c_str(), ".") == 0 ||
      strcmp(fname.c_str(), "..") == 0  )
      {
      continue;
      }

    if ( start == 0 )
      {
      realname = dir + fname;
      }
    else
      {
      realname = dir + "/" + fname;
      }

#if defined(KWSYS_GLOB_CASE_INDEPENDENT)
    // On case-insensitive file systems convert to lower case for matching.
    fname = kwsys::SystemTools::LowerCase(fname);
#endif

    if ( start == 0 )
      {
      fullname = dir + fname;
      }
    else
      {
      fullname = dir + "/" + fname;
      }

    //kwsys_ios::cout << "Look at file: " << fname << kwsys_ios::endl;
    //kwsys_ios::cout << "Match: "
    // << this->Internals->TextExpressions[start].c_str() << kwsys_ios::endl;
    //kwsys_ios::cout << "Full name: " << fullname << kwsys_ios::endl;

    if ( !last &&
      !kwsys::SystemTools::FileIsDirectory(realname.c_str()) )
      {
      continue;
      }

    if ( this->Internals->Expressions[start].find(fname.c_str()) )
      {
      if ( last )
        {
        this->AddFile(this->Internals->Files, realname.c_str());
        }
      else
        {
        this->ProcessDirectory(start+1, realname + "/");
        }
      }
    }
}

//----------------------------------------------------------------------------
bool Glob::FindFiles(const kwsys_stl::string& inexpr)
{
  kwsys_stl::string cexpr;
  kwsys_stl::string::size_type cc;
  kwsys_stl::string expr = inexpr;

  this->Internals->Expressions.clear();
  this->Internals->Files.clear();

  if ( !kwsys::SystemTools::FileIsFullPath(expr.c_str()) )
    {
    expr = kwsys::SystemTools::GetCurrentWorkingDirectory();
    expr += "/" + inexpr;
    }
  kwsys_stl::string fexpr = expr;

  kwsys_stl::string::size_type skip = 0;
  kwsys_stl::string::size_type last_slash = 0;
  for ( cc = 0; cc < expr.size(); cc ++ )
    {
    if ( cc > 0 && expr[cc] == '/' && expr[cc-1] != '\\' )
      {
      last_slash = cc;
      }
    if ( cc > 0 &&
      (expr[cc] == '[' || expr[cc] == '?' || expr[cc] == '*') &&
      expr[cc-1] != '\\' )
      {
      break;
      }
    }
  if ( last_slash > 0 )
    {
    //kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
    //<< kwsys_ios::endl;
    skip = last_slash;
    }
  if ( skip == 0 )
    {
#if defined( KWSYS_GLOB_SUPPORT_NETWORK_PATHS )
    // Handle network paths
    if ( expr[0] == '/' && expr[1] == '/' )
      {
      int cnt = 0;
      for ( cc = 2; cc < expr.size(); cc ++ )
        {
        if ( expr[cc] == '/' )
          {
          cnt ++;
          if ( cnt == 2 )
            {
            break;
            }
          }
        }
      skip = int(cc + 1);
      }
    else
#endif
      // Handle drive letters on Windows
      if ( expr[1] == ':' && expr[0] != '/' )
        {
        skip = 2;
        }
    }

  if ( skip > 0 )
    {
    expr = expr.substr(skip);
    }

  cexpr = "";
  for ( cc = 0; cc < expr.size(); cc ++ )
    {
    int ch = expr[cc];
    if ( ch == '/' )
      {
      if ( cexpr.size() > 0 )
        {
        this->AddExpression(cexpr.c_str());
        }
      cexpr = "";
      }
    else
      {
      cexpr.append(1, static_cast<char>(ch));
      }
    }
  if ( cexpr.size() > 0 )
    {
    this->AddExpression(cexpr.c_str());
    }

  // Handle network paths
  if ( skip > 0 )
    {
    this->ProcessDirectory(0, fexpr.substr(0, skip) + "/");
    }
  else
    {
    this->ProcessDirectory(0, "/");
    }
  return true;
}

//----------------------------------------------------------------------------
void Glob::AddExpression(const char* expr)
{
  this->Internals->Expressions.push_back(
    kwsys::RegularExpression(
      this->PatternToRegex(expr).c_str()));
}

//----------------------------------------------------------------------------
void Glob::SetRelative(const char* dir)
{
  if ( !dir )
    {
    this->Relative = "";
    return;
    }
  this->Relative = dir;
}

//----------------------------------------------------------------------------
const char* Glob::GetRelative()
{
  if ( this->Relative.empty() )
    {
    return 0;
    }
  return this->Relative.c_str();
}

//----------------------------------------------------------------------------
void Glob::AddFile(kwsys_stl::vector<kwsys_stl::string>& files, const char* file)
{
  if ( !this->Relative.empty() )
    {
    files.push_back(kwsys::SystemTools::RelativePath(this->Relative.c_str(), file));
    }
  else
    {
    files.push_back(file);
    }
}

} // namespace KWSYS_NAMESPACE

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "Operations.h"
#include <future>
#include <iostream>
#include <thread>
#include <stdio.h>

LVPM::LVPM() noexcept
{
	handle =NULL;
	for (int i = 0; i < QueueSize; i++)
	{
		Packets[i] = 0;
	}
}

void LVPM::setup_usb(int serialno)
{
	handle = openDevice(VendorID, ProductID,serialno);
}

void LVPM::setVout(float value)
{
	int conversion = 1048576 * value;
	unsigned char opcode = 0x41;
	sendCommand(handle, opcode, conversion);
}
void LVPM::Close()
{
	closeDevice(handle);
}

void LVPM::Start(int calTime, int maxTime)
{
	totalSampleCount = 0;
	startSampling(handle, calTime, maxTime);
	running = true;
	swizzleThread = thread(&LVPM::Enque, this);
	processThread = thread(&LVPM::ProcessPackets, this);

}

void LVPM::Stop()
{
	signalLock.lock();
	running = false;
	signalLock.unlock();
	stopSampling(handle);
	swizzleThread.join();
	processThread.join();
}

void LVPM::getCalValues()
{
	mainFineResistor = factoryResistor + getValue(handle, setMainFineResistorOffset, 1) * 0.0001;
	mainCoarseResistor = factoryResistor + getValue(handle, setMainCoarseResistorOffset, 1) * 0.0001;

	mainFineScale = 35946.0 * (factoryResistor / mainFineResistor);
	mainCoarseScale = 3103.4 * (factoryResistor / mainCoarseResistor);
}

void LVPM::SwizzlePackets(unsigned char* Packets, int numPackets)
{
	int offset = 0;

	for (int i = 0; i < numPackets; i++)
	{
		std::vector<unsigned char> Packet;

		unsigned char packetStart = i * packetLength;
		Packet.push_back(Packets[packetStart]);
		Packet.push_back(Packets[packetStart + 1]);
		Packet.push_back(Packets[packetStart + 2]);
		Packet.push_back(Packets[packetStart + 3]);
		for (offset = 4; offset < packetLength; offset += 2)
		{
			Packet.push_back(Packets[packetStart + offset + 1]);
			Packet.push_back(Packets[packetStart + offset]);
		}
		QueueAccess.lock();
		ProcessQueue.push(Packet);
		QueueAccess.unlock();
	}
}

void LVPM::Enque()
{
	while (running)
	{
		int count = getSamples(Packets, QueueSize);
		SwizzlePackets(Packets, count);
	}
}

void LVPM::ProcessPackets()
{
	while (running)
	{
		if (!ProcessQueue.empty())
		{
			QueueAccess.lock();
			std::vector<unsigned char> Packet = ProcessQueue.front();
			ProcessQueue.pop();
			QueueAccess.unlock();
			int offset = 0;
			unsigned int dropped = ((Packet[offset] << 8) | Packet[offset + 1]);
			offset += 2;
			int flags = Packet[offset++];
			int numObs = Packet[offset++];

			for (int ob = 0; ob < numObs; ob++)
			{
				totalSampleCount++;
				bool Coarse = false;
				short Raw = 0;
				float res = mainFineResistor;
				float CalRef = mainFineRefCal;
				float CalZero = mainFineZeroCal;
				float scale = mainFineScale;

				short mainCoarse = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 2;
				short mainFine = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 10; //Skipping USB and Aux channels for now
				short mainVoltage = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 4; //Skipping over USB voltage, Main Gain.
				unsigned char PacketType = Packet[offset] & 0x30;
				offset += 2;

				float slope = 0;
				float Current = 0;
				float voltage = 0;
				//printf("StatusType: %d \n", PacketType);
				switch (PacketType)
				{
				case 0x10: //ZeroCal
					mainFineZeroCal = mainFine;
					mainCoarseZeroCal = mainCoarse;
					break;
				case 0x30: //Refcal
					mainFineRefCal = mainFine;
					mainCoarseRefCal = mainCoarse;
					break;
				case 0x00: //Measurement
					if (Calibrated())
					{
						if (mainFine > 30000)
						{
							Coarse = true;
							Raw = mainCoarse;
							scale = mainCoarseScale;
							CalRef = mainCoarseRefCal;
							CalZero = mainCoarseZeroCal;
						}
						else
						{
							Coarse = false;
							Raw = mainFine;
							scale = mainFineScale;
							CalRef = mainFineRefCal;
							CalZero = mainFineZeroCal;
						}
						slope = scale / (CalRef - CalZero);
						Current = slope * (Raw - CalZero);
						if (!Coarse)
						{
							Current /= 1000; //uA -> mA
						}
						voltage = mainVoltage * (62.5 / 1e6) * 2;

						if (totalSampleCount % 1000 == 0)
						{
							printf("Current: %4.2f Voltage: %4.2f Dropped: %d Total Samples: %d \n", Current, voltage, dropped, totalSampleCount);
						}

					}
					break;
				default:

					break;
				}

			}
		}
	}

}
bool LVPM::Calibrated()
{
	return mainFineRefCal != 0 &&
		mainCoarseRefCal != 0 &&
		mainFineZeroCal != 0 &&
		mainCoarseZeroCal != 0;
}
<commit_msg>Remove test clutter.<commit_after>#include "stdafx.h"
#include "Operations.h"
#include <future>
#include <iostream>
#include <thread>
#include <stdio.h>

LVPM::LVPM() noexcept
{
	handle =NULL;
	for (int i = 0; i < QueueSize; i++)
	{
		Packets[i] = 0;
	}
}

void LVPM::setup_usb(int serialno)
{
	handle = openDevice(VendorID, ProductID,serialno);
}

void LVPM::setVout(float value)
{
	int conversion = 1048576 * value;
	unsigned char opcode = 0x41;
	sendCommand(handle, opcode, conversion);
}
void LVPM::Close()
{
	closeDevice(handle);
}

void LVPM::Start(int calTime, int maxTime)
{
	totalSampleCount = 0;
	startSampling(handle, calTime, maxTime);
	running = true;
	swizzleThread = thread(&LVPM::Enque, this);
	processThread = thread(&LVPM::ProcessPackets, this);

}

void LVPM::Stop()
{
	running = false;
	stopSampling(handle);
	swizzleThread.join();
	processThread.join();
}

void LVPM::getCalValues()
{
	mainFineResistor = factoryResistor + getValue(handle, setMainFineResistorOffset, 1) * 0.0001;
	mainCoarseResistor = factoryResistor + getValue(handle, setMainCoarseResistorOffset, 1) * 0.0001;

	mainFineScale = 35946.0 * (factoryResistor / mainFineResistor);
	mainCoarseScale = 3103.4 * (factoryResistor / mainCoarseResistor);
}

void LVPM::SwizzlePackets(unsigned char* Packets, int numPackets)
{
	int offset = 0;

	for (int i = 0; i < numPackets; i++)
	{
		std::vector<unsigned char> Packet;

		unsigned char packetStart = i * packetLength;
		Packet.push_back(Packets[packetStart]);
		Packet.push_back(Packets[packetStart + 1]);
		Packet.push_back(Packets[packetStart + 2]);
		Packet.push_back(Packets[packetStart + 3]);
		for (offset = 4; offset < packetLength; offset += 2)
		{
			Packet.push_back(Packets[packetStart + offset + 1]);
			Packet.push_back(Packets[packetStart + offset]);
		}
		QueueAccess.lock();
		ProcessQueue.push(Packet);
		QueueAccess.unlock();
	}
}

void LVPM::Enque()
{
	while (running)
	{
		int count = getSamples(Packets, QueueSize);
		SwizzlePackets(Packets, count);
	}
}

void LVPM::ProcessPackets()
{
	while (running)
	{
		if (!ProcessQueue.empty())
		{
			QueueAccess.lock();
			std::vector<unsigned char> Packet = ProcessQueue.front();
			ProcessQueue.pop();
			QueueAccess.unlock();
			int offset = 0;
			unsigned int dropped = ((Packet[offset] << 8) | Packet[offset + 1]);
			offset += 2;
			int flags = Packet[offset++];
			int numObs = Packet[offset++];

			for (int ob = 0; ob < numObs; ob++)
			{
				totalSampleCount++;
				bool Coarse = false;
				short Raw = 0;
				float res = mainFineResistor;
				float CalRef = mainFineRefCal;
				float CalZero = mainFineZeroCal;
				float scale = mainFineScale;

				short mainCoarse = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 2;
				short mainFine = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 10; //Skipping USB and Aux channels for now
				short mainVoltage = ((Packet[offset + 1] << 8) | Packet[offset]);
				offset += 4; //Skipping over USB voltage, Main Gain.
				unsigned char PacketType = Packet[offset] & 0x30;
				offset += 2;

				float slope = 0;
				float Current = 0;
				float voltage = 0;
				//printf("StatusType: %d \n", PacketType);
				switch (PacketType)
				{
				case 0x10: //ZeroCal
					mainFineZeroCal = mainFine;
					mainCoarseZeroCal = mainCoarse;
					break;
				case 0x30: //Refcal
					mainFineRefCal = mainFine;
					mainCoarseRefCal = mainCoarse;
					break;
				case 0x00: //Measurement
					if (Calibrated())
					{
						if (mainFine > 30000)
						{
							Coarse = true;
							Raw = mainCoarse;
							scale = mainCoarseScale;
							CalRef = mainCoarseRefCal;
							CalZero = mainCoarseZeroCal;
						}
						else
						{
							Coarse = false;
							Raw = mainFine;
							scale = mainFineScale;
							CalRef = mainFineRefCal;
							CalZero = mainFineZeroCal;
						}
						slope = scale / (CalRef - CalZero);
						Current = slope * (Raw - CalZero);
						if (!Coarse)
						{
							Current /= 1000; //uA -> mA
						}
						voltage = mainVoltage * (62.5 / 1e6) * 2;

						if (totalSampleCount % 1000 == 0)
						{
							printf("Current: %4.2f Voltage: %4.2f Dropped: %d Total Samples: %d \n", Current, voltage, dropped, totalSampleCount);
						}

					}
					break;
				default:

					break;
				}

			}
		}
	}

}
bool LVPM::Calibrated()
{
	return mainFineRefCal != 0 &&
		mainCoarseRefCal != 0 &&
		mainFineZeroCal != 0 &&
		mainCoarseZeroCal != 0;
}
<|endoftext|>


<commit_before>#include "StableHeaders.h"
#include "Session.h"
//#include "MemoryLeakCheck.h"
#include "ServerInfo.h"
#include "PCMAudioFrame.h"
#include "Vector3D.h"
#include "EC_OgrePlaceable.h" // for avatar position
#include "EC_OpenSimPresence.h" // for avatar position
#include "ModuleManager.h"    // for avatar info
#include "WorldLogicInterface.h" // for avatar position
#include "Entity.h" // for avatar position
#include "SceneManager.h"
#include "WorldStream.h"
#include "User.h"
#include "Channel.h"
#include "Connection.h"
#include "Participant.h"
#include "MumbleLibrary.h"
#include "MumbleVoipModule.h"

//#define BUILDING_DLL // for dll import/export declarations
//#define CreateEvent  CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
////#include <mumbleclient/client_lib.h>
//#undef BUILDING_DLL // for dll import/export declarations
////#include "LibMumbleThread.h"

namespace MumbleVoip
{
    namespace InWorldVoice
    {
        Session::Session(Foundation::Framework* framework, const ServerInfo &server_info) :
            state_(STATE_INITIALIZING),
            reason_(""),
            framework_(framework),
            description_(""),
            sending_audio_(false),
            receiving_audio_(false),
            audio_sending_enabled_(false),
            audio_receiving_enabled_(false),
            speaker_voice_activity_(0),
//            connection_manager_(new ConnectionManager(framework)),
            server_info_(server_info),
            connection_(0)
        {
            channel_name_ = server_info.channel;
            OpenConnection(server_info);

            //connection_manager_->OpenConnection(server_info);
            //if (connection_manager_->GetState() != ConnectionManager::STATE_CONNECTION_OPEN)
            //{
            //    state_ = STATE_ERROR;
            //    reason_ = connection_manager_->GetReason();
            //    return;
            //}
        }

        Session::~Session()
        {
            foreach(Participant* p, participants_)
            {
                SAFE_DELETE(p);
            }
            participants_.clear();
            foreach(Participant* p, left_participants_)
            {
                SAFE_DELETE(p);
            }
            left_participants_.clear();
            if (connection_)
                SAFE_DELETE(connection_);
        }

        void Session::OpenConnection(ServerInfo server_info)
        {
            connection_ = new Connection(server_info);
            if (connection_->GetState() == Connection::STATE_ERROR)
            {
                state_ = STATE_ERROR;
                reason_ = connection_->GetReason();
                return;
            }
            state_ = STATE_OPEN;

            connect(connection_, SIGNAL(UserJoined(User*)), SLOT(CreateNewParticipant(User*)) );
            connect(connection_, SIGNAL(UserLeft(User*)), SLOT(UpdateUserList()) );
//            connections_[info.server] = connection;
            connection_->Join(server_info.channel);
            connection_->SendAudio(sending_audio_);
            connection_->SetEncodingQuality(0.5);
            connection_->SendPosition(true);
            MumbleLibrary::Start();
            MumbleLibrary::Stop();
            //connect(MumbleLibrary::Instance(), SIGNAL(InteralError()), SLOT(HandleMumbleLibraryError()) );
//            connect(connection_manager_, SIGNAL(AudioFrameSent(PCMAudioFrame*)), SLOT(UpdateSpeakerActivity(PCMAudioFrame*)) );
        }

        void Session::Close()
        {
            connection_->Close();
            SAFE_DELETE(connection_);
            state_ = STATE_CLOSED;
            emit StateChanged(state_);
        }

        Communications::InWorldVoice::SessionInterface::State Session::GetState() const
        {
            return state_;
        }

        QString Session::Reason() const
        {
            return reason_;
        }

        QString Session::Description() const
        {
            return description_;
        }

        bool Session::IsSendingAudio() const
        {
            return sending_audio_;
        }

        bool Session::IsReceivingAudio() const
        {
            return receiving_audio_;
        }

        void Session::EnableAudioSending()
        {
            if (connection_)
                connection_->SendAudio(true);
            bool audio_sending_was_enabled = audio_sending_enabled_;
            audio_sending_enabled_ = true;
            if (!audio_sending_was_enabled)
            {
                boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
                if (sound_service.get())
                {
                    int frequency = SAMPLE_RATE;
                    bool sixteenbit = true;
                    bool stereo = false;
                    int buffer_size = SAMPLE_WIDTH/8*frequency*AUDIO_RECORDING_BUFFER_MS/1000;
                    sound_service->StartRecording(recording_device_, frequency, sixteenbit, stereo, buffer_size);
                }

                emit StartSendingAudio();
            }
        }

        void Session::DisableAudioSending()
        {
            if (connection_)
                connection_->SendAudio(false);
            bool audio_sending_was_enabled = audio_sending_enabled_;
            audio_sending_enabled_ = false;
            if (audio_sending_was_enabled)
            {
                boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
                if (sound_service.get())
                    sound_service->StopRecording();

                emit StopSendingAudio();
            }
        }

        bool Session::IsAudioSendingEnabled() const
        {
            return audio_sending_enabled_;
        }

        void Session::EnableAudioReceiving()
        {
            if (connection_)
                connection_->ReceiveAudio(true);
            audio_receiving_enabled_ = true;
        }

        void Session::DisableAudioReceiving()
        {
            if (connection_)
                connection_->ReceiveAudio(false);
            audio_receiving_enabled_ = false;
        }

        bool Session::IsAudioReceivingEnabled() const
        {
            return audio_receiving_enabled_;
        }

        double Session::SpeakerVoiceActivity() const
        {
            return speaker_voice_activity_;
        }

        QList<Communications::InWorldVoice::ParticipantInterface*> Session::Participants() const
        {
            QList<Communications::InWorldVoice::ParticipantInterface*> list;
            for(ParticipantList::const_iterator i = participants_.begin(); i != participants_.end(); ++i)
            {
                Participant* p = *i;
                list.append(static_cast<Communications::InWorldVoice::ParticipantInterface*>(p));
            }
            return list;
        }

        void Session::Update(f64 frametime)
        {
//                connection_manager_->Update(frametime);
            PlaybackReceivedAudio();
            SendRecordedAudio();
        }

        void Session::CreateNewParticipant(User* user)
        {
            if (user->Name() == OwnAvatarId())
            {
                self_user_ = user;
                return;
            }

            if (user->Channel()->FullName() != channel_name_)
                return;

            QString uuid = user->Name();
            QString name = GetAvatarFullName(uuid);
            if (name.size() == 0)
                name = QString("(Unknow) %0").arg(user->Name());
            Participant* p = new Participant(name, user);
            participants_.append(p);
            connect(p, SIGNAL(StartSpeaking()), SLOT(OnUserStartSpeaking()) );
            connect(p, SIGNAL(StopSpeaking()), SLOT(OnUserStopSpeaking()) );
            connect(p, SIGNAL(Left()), SLOT(UpdateParticipantList()) );

            emit ParticipantJoined((Communications::InWorldVoice::ParticipantInterface*)p);
        }

        void Session::UpdateParticipantList()
        {
            foreach(Participant* p, participants_)
            {
                if (p->UserPtr()->IsLeft())
                {
                    participants_.removeOne(p);
                    left_participants_.push_back(p);
                    emit ParticipantLeft(p);
                }
            }
        }

        void Session::OnUserStartSpeaking()
        {
            bool was_receiving_audio = receiving_audio_;
            receiving_audio_ = true;
            if (!was_receiving_audio)
                emit StartReceivingAudio();
        }

        void Session::OnUserStopSpeaking()
        {
            bool was_receiving_audio = receiving_audio_;
            foreach(Participant* p, participants_)
            {
                if (p->IsSpeaking())
                {
                    receiving_audio_ = true;
                    return;
                }
            }
            receiving_audio_ = false;
            if (was_receiving_audio)
                emit StopReceivingAudio();
        }

        void Session::UpdateSpeakerActivity(PCMAudioFrame* frame)
        {
            static int counter;
            counter++;
            counter = counter % 10;
            if (counter != 0)
                return;

            short top = 0;
            const short max = 100; //! \todo Use more proper treshold value
            for(int i = 0; i < frame->SampleCount(); ++i)
            {
                int sample = abs(frame->SampleAt(i));
                if (sample > top)
                    top = sample;
            }

            double activity = top / max;
            if (activity > 1.0)
                activity = 1.0;

            double old_activity = speaker_voice_activity_;
            speaker_voice_activity_ = activity;
            if (old_activity != activity)
                emit Communications::InWorldVoice::SessionInterface::SpeakerVoiceActivityChanged(activity);
        }

        bool Session::GetOwnAvatarPosition(Vector3df& position, Vector3df& direction)
        {
            using namespace Foundation;
            boost::shared_ptr<WorldLogicInterface> world_logic = framework_->GetServiceManager()->GetService<WorldLogicInterface>(Service::ST_WorldLogic).lock();
            if (!world_logic)
                return false;

            Scene::EntityPtr user_avatar = world_logic->GetUserAvatarEntity();
            if (!user_avatar)
                return false;

            boost::shared_ptr<OgreRenderer::EC_OgrePlaceable> ogre_placeable = user_avatar->GetComponent<OgreRenderer::EC_OgrePlaceable>();
            if (!ogre_placeable)
                return false;

            Quaternion q = ogre_placeable->GetOrientation();
            position = ogre_placeable->GetPosition();
            direction = q*Vector3df::UNIT_Z;

            return true;
        }

        QString Session::OwnAvatarId()
        {
            using namespace Foundation;
            boost::shared_ptr<WorldLogicInterface> world_logic = framework_->GetServiceManager()->GetService<WorldLogicInterface>(Service::ST_WorldLogic).lock();
            if (!world_logic)
                return "";

            Scene::EntityPtr user_avatar = world_logic->GetUserAvatarEntity();
            if (!user_avatar)
                return "";

            boost::shared_ptr<EC_OpenSimPresence> opensim_presence = user_avatar->GetComponent<EC_OpenSimPresence>();
            if (!opensim_presence)
                return "";

            return opensim_presence->agentId.ToQString();
        }

        QString Session::GetAvatarFullName(QString uuid) const
        {
            Scene::ScenePtr current_scene = framework_->GetDefaultWorldScene();
            if (current_scene.get())
            {
                for(Scene::SceneManager::iterator iter = current_scene->begin(); iter != current_scene->end(); ++iter)
                {
                    Scene::Entity &entity = **iter;
                    EC_OpenSimPresence *presence_component = entity.GetComponent<EC_OpenSimPresence>().get();
                    if (presence_component)
                        if (presence_component->agentId.ToQString() == uuid)
                            return QString(presence_component->GetFullName().c_str());
                }
            }
            return "";
        }

        void Session::SendRecordedAudio()
        {
			if (!connection_)
				return;

            if (!audio_sending_enabled_)
                return;

            Vector3df avatar_position;
            Vector3df avatar_direction;

            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
            if (!sound_service)
            {
                MumbleVoipModule::LogDebug("Cannot record audio: Soundservice cannot be found.");
                return;
            }

            while (sound_service->GetRecordedSoundSize() > SAMPLES_IN_FRAME*SAMPLE_WIDTH/8)
            {
                int bytes_to_read = SAMPLES_IN_FRAME*SAMPLE_WIDTH/8;
                PCMAudioFrame* frame = new PCMAudioFrame(SAMPLE_RATE, SAMPLE_WIDTH, NUMBER_OF_CHANNELS, bytes_to_read );
                int bytes = sound_service->GetRecordedSoundData(frame->DataPtr(), bytes_to_read);
                assert(bytes_to_read == bytes);

                //if (voice_indicator_)
                //{
                //    voice_indicator_->AnalyzeAudioFrame(frame);
                //    if (!voice_indicator_->IsSpeaking())
                //    {
                //        delete frame;
                //        continue;
                //    }
                //}
                connection_->SendAudioFrame(frame, avatar_position);
//                emit AudioFrameSent(frame);
                delete frame;
            }
        }

        void Session::PlaybackReceivedAudio()
        {
			if (!connection_)
				return;

			if (!audio_sending_enabled_)
				return;

            for(;;)
            {
                AudioPacket packet = connection_->GetAudioPacket();
                if (packet.second == 0)
                    break; // nothing to play anymore
                PlaybackAudioFrame(packet.first, packet.second);
            }
        }

        void Session::PlaybackAudioFrame(User* user, PCMAudioFrame* frame)
        {
            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
            if (!sound_service.get())
                return;

            Foundation::SoundServiceInterface::SoundBuffer sound_buffer;

            sound_buffer.data_.resize(frame->DataSize());
            memcpy(&sound_buffer.data_[0], frame->DataPtr(), frame->DataSize());

            sound_buffer.frequency_ = frame->SampleRate();
            if (frame->SampleWidth() == 16)
                sound_buffer.sixteenbit_ = true;
            else
                sound_buffer.sixteenbit_ = false;

            if (frame->Channels() == 2)
                sound_buffer.stereo_ = true;
            else
                sound_buffer.stereo_ = false;

            QMutexLocker user_locker(user);
            if (audio_playback_channels_.contains(user->Session()))
                if (user->PositionKnown())
                    sound_service->PlaySoundBuffer3D(sound_buffer, Foundation::SoundServiceInterface::Voice, user->Position(), audio_playback_channels_[user->Session()]);
                else
                    sound_service->PlaySoundBuffer(sound_buffer,  Foundation::SoundServiceInterface::Voice, audio_playback_channels_[user->Session()]);
            else
                if (user->PositionKnown())
                    audio_playback_channels_[user->Session()] = sound_service->PlaySoundBuffer3D(sound_buffer, Foundation::SoundServiceInterface::Voice, user->Position(), 0);
                else
                    audio_playback_channels_[user->Session()] = sound_service->PlaySoundBuffer(sound_buffer,  Foundation::SoundServiceInterface::Voice, 0);

            delete frame;
        }

        boost::shared_ptr<Foundation::SoundServiceInterface> Session::SoundService()
        {
            if (!framework_)
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            Foundation::ServiceManagerPtr service_manager = framework_->GetServiceManager();

            if (!service_manager.get())
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = service_manager->GetService<Foundation::SoundServiceInterface>(Foundation::Service::ST_Sound).lock();

            if (!sound_service.get())
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            return sound_service;
        }

    } // InWorldVoice

} // MumbleVoip
<commit_msg>Fixed participant mute.<commit_after>#include "StableHeaders.h"
#include "Session.h"
//#include "MemoryLeakCheck.h"
#include "ServerInfo.h"
#include "PCMAudioFrame.h"
#include "Vector3D.h"
#include "EC_OgrePlaceable.h" // for avatar position
#include "EC_OpenSimPresence.h" // for avatar position
#include "ModuleManager.h"    // for avatar info
#include "WorldLogicInterface.h" // for avatar position
#include "Entity.h" // for avatar position
#include "SceneManager.h"
#include "WorldStream.h"
#include "User.h"
#include "Channel.h"
#include "Connection.h"
#include "Participant.h"
#include "MumbleLibrary.h"
#include "MumbleVoipModule.h"

//#define BUILDING_DLL // for dll import/export declarations
//#define CreateEvent  CreateEventW // for \boost\asio\detail\win_event.hpp and \boost\asio\detail\win_iocp_handle_service.hpp
////#include <mumbleclient/client_lib.h>
//#undef BUILDING_DLL // for dll import/export declarations
////#include "LibMumbleThread.h"

namespace MumbleVoip
{
    namespace InWorldVoice
    {
        Session::Session(Foundation::Framework* framework, const ServerInfo &server_info) :
            state_(STATE_INITIALIZING),
            reason_(""),
            framework_(framework),
            description_(""),
            sending_audio_(false),
            receiving_audio_(false),
            audio_sending_enabled_(false),
            audio_receiving_enabled_(false),
            speaker_voice_activity_(0),
//            connection_manager_(new ConnectionManager(framework)),
            server_info_(server_info),
            connection_(0)
        {
            channel_name_ = server_info.channel;
            OpenConnection(server_info);

            //connection_manager_->OpenConnection(server_info);
            //if (connection_manager_->GetState() != ConnectionManager::STATE_CONNECTION_OPEN)
            //{
            //    state_ = STATE_ERROR;
            //    reason_ = connection_manager_->GetReason();
            //    return;
            //}
        }

        Session::~Session()
        {
            foreach(Participant* p, participants_)
            {
                SAFE_DELETE(p);
            }
            participants_.clear();
            foreach(Participant* p, left_participants_)
            {
                SAFE_DELETE(p);
            }
            left_participants_.clear();
            if (connection_)
                SAFE_DELETE(connection_);
        }

        void Session::OpenConnection(ServerInfo server_info)
        {
            connection_ = new Connection(server_info);
            if (connection_->GetState() == Connection::STATE_ERROR)
            {
                state_ = STATE_ERROR;
                reason_ = connection_->GetReason();
                return;
            }
            state_ = STATE_OPEN;

            connect(connection_, SIGNAL(UserJoined(User*)), SLOT(CreateNewParticipant(User*)) );
            connect(connection_, SIGNAL(UserLeft(User*)), SLOT(UpdateUserList()) );
//            connections_[info.server] = connection;
            connection_->Join(server_info.channel);
            connection_->SendAudio(sending_audio_);
            connection_->SetEncodingQuality(0.5);
            connection_->SendPosition(true);
            MumbleLibrary::Start();
            MumbleLibrary::Stop();
            //connect(MumbleLibrary::Instance(), SIGNAL(InteralError()), SLOT(HandleMumbleLibraryError()) );
//            connect(connection_manager_, SIGNAL(AudioFrameSent(PCMAudioFrame*)), SLOT(UpdateSpeakerActivity(PCMAudioFrame*)) );
        }

        void Session::Close()
        {
            connection_->Close();
            SAFE_DELETE(connection_);
            state_ = STATE_CLOSED;
            emit StateChanged(state_);
        }

        Communications::InWorldVoice::SessionInterface::State Session::GetState() const
        {
            return state_;
        }

        QString Session::Reason() const
        {
            return reason_;
        }

        QString Session::Description() const
        {
            return description_;
        }

        bool Session::IsSendingAudio() const
        {
            return sending_audio_;
        }

        bool Session::IsReceivingAudio() const
        {
            return receiving_audio_;
        }

        void Session::EnableAudioSending()
        {
            if (connection_)
                connection_->SendAudio(true);
            bool audio_sending_was_enabled = audio_sending_enabled_;
            audio_sending_enabled_ = true;
            if (!audio_sending_was_enabled)
            {
                boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
                if (sound_service.get())
                {
                    int frequency = SAMPLE_RATE;
                    bool sixteenbit = true;
                    bool stereo = false;
                    int buffer_size = SAMPLE_WIDTH/8*frequency*AUDIO_RECORDING_BUFFER_MS/1000;
                    sound_service->StartRecording(recording_device_, frequency, sixteenbit, stereo, buffer_size);
                }

                emit StartSendingAudio();
            }
        }

        void Session::DisableAudioSending()
        {
            if (connection_)
                connection_->SendAudio(false);
            bool audio_sending_was_enabled = audio_sending_enabled_;
            audio_sending_enabled_ = false;
            if (audio_sending_was_enabled)
            {
                boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
                if (sound_service.get())
                    sound_service->StopRecording();

                emit StopSendingAudio();
            }
        }

        bool Session::IsAudioSendingEnabled() const
        {
            return audio_sending_enabled_;
        }

        void Session::EnableAudioReceiving()
        {
            if (connection_)
                connection_->ReceiveAudio(true);
            audio_receiving_enabled_ = true;
        }

        void Session::DisableAudioReceiving()
        {
            if (connection_)
                connection_->ReceiveAudio(false);
            audio_receiving_enabled_ = false;
        }

        bool Session::IsAudioReceivingEnabled() const
        {
            return audio_receiving_enabled_;
        }

        double Session::SpeakerVoiceActivity() const
        {
            return speaker_voice_activity_;
        }

        QList<Communications::InWorldVoice::ParticipantInterface*> Session::Participants() const
        {
            QList<Communications::InWorldVoice::ParticipantInterface*> list;
            for(ParticipantList::const_iterator i = participants_.begin(); i != participants_.end(); ++i)
            {
                Participant* p = *i;
                list.append(static_cast<Communications::InWorldVoice::ParticipantInterface*>(p));
            }
            return list;
        }

        void Session::Update(f64 frametime)
        {
//                connection_manager_->Update(frametime);
            PlaybackReceivedAudio();
            SendRecordedAudio();
        }

        void Session::CreateNewParticipant(User* user)
        {
            if (user->Name() == OwnAvatarId())
            {
                self_user_ = user;
                return;
            }

            if (user->Channel()->FullName() != channel_name_)
                return;

            QString uuid = user->Name();
            QString name = GetAvatarFullName(uuid);
            if (name.size() == 0)
                name = QString("(Unknow) %0").arg(user->Name());
            Participant* p = new Participant(name, user);
            participants_.append(p);
            connect(p, SIGNAL(StartSpeaking()), SLOT(OnUserStartSpeaking()) );
            connect(p, SIGNAL(StopSpeaking()), SLOT(OnUserStopSpeaking()) );
            connect(p, SIGNAL(Left()), SLOT(UpdateParticipantList()) );

            emit ParticipantJoined((Communications::InWorldVoice::ParticipantInterface*)p);
        }

        void Session::UpdateParticipantList()
        {
            foreach(Participant* p, participants_)
            {
                if (p->UserPtr()->IsLeft())
                {
                    participants_.removeOne(p);
                    left_participants_.push_back(p);
                    emit ParticipantLeft(p);
                }
            }
        }

        void Session::OnUserStartSpeaking()
        {
            bool was_receiving_audio = receiving_audio_;
            receiving_audio_ = true;
            if (!was_receiving_audio)
                emit StartReceivingAudio();
        }

        void Session::OnUserStopSpeaking()
        {
            bool was_receiving_audio = receiving_audio_;
            foreach(Participant* p, participants_)
            {
                if (p->IsSpeaking())
                {
                    receiving_audio_ = true;
                    return;
                }
            }
            receiving_audio_ = false;
            if (was_receiving_audio)
                emit StopReceivingAudio();
        }

        void Session::UpdateSpeakerActivity(PCMAudioFrame* frame)
        {
            static int counter;
            counter++;
            counter = counter % 10;
            if (counter != 0)
                return;

            short top = 0;
            const short max = 100; //! \todo Use more proper treshold value
            for(int i = 0; i < frame->SampleCount(); ++i)
            {
                int sample = abs(frame->SampleAt(i));
                if (sample > top)
                    top = sample;
            }

            double activity = top / max;
            if (activity > 1.0)
                activity = 1.0;

            double old_activity = speaker_voice_activity_;
            speaker_voice_activity_ = activity;
            if (old_activity != activity)
                emit Communications::InWorldVoice::SessionInterface::SpeakerVoiceActivityChanged(activity);
        }

        bool Session::GetOwnAvatarPosition(Vector3df& position, Vector3df& direction)
        {
            using namespace Foundation;
            boost::shared_ptr<WorldLogicInterface> world_logic = framework_->GetServiceManager()->GetService<WorldLogicInterface>(Service::ST_WorldLogic).lock();
            if (!world_logic)
                return false;

            Scene::EntityPtr user_avatar = world_logic->GetUserAvatarEntity();
            if (!user_avatar)
                return false;

            boost::shared_ptr<OgreRenderer::EC_OgrePlaceable> ogre_placeable = user_avatar->GetComponent<OgreRenderer::EC_OgrePlaceable>();
            if (!ogre_placeable)
                return false;

            Quaternion q = ogre_placeable->GetOrientation();
            position = ogre_placeable->GetPosition();
            direction = q*Vector3df::UNIT_Z;

            return true;
        }

        QString Session::OwnAvatarId()
        {
            using namespace Foundation;
            boost::shared_ptr<WorldLogicInterface> world_logic = framework_->GetServiceManager()->GetService<WorldLogicInterface>(Service::ST_WorldLogic).lock();
            if (!world_logic)
                return "";

            Scene::EntityPtr user_avatar = world_logic->GetUserAvatarEntity();
            if (!user_avatar)
                return "";

            boost::shared_ptr<EC_OpenSimPresence> opensim_presence = user_avatar->GetComponent<EC_OpenSimPresence>();
            if (!opensim_presence)
                return "";

            return opensim_presence->agentId.ToQString();
        }

        QString Session::GetAvatarFullName(QString uuid) const
        {
            Scene::ScenePtr current_scene = framework_->GetDefaultWorldScene();
            if (current_scene.get())
            {
                for(Scene::SceneManager::iterator iter = current_scene->begin(); iter != current_scene->end(); ++iter)
                {
                    Scene::Entity &entity = **iter;
                    EC_OpenSimPresence *presence_component = entity.GetComponent<EC_OpenSimPresence>().get();
                    if (presence_component)
                        if (presence_component->agentId.ToQString() == uuid)
                            return QString(presence_component->GetFullName().c_str());
                }
            }
            return "";
        }

        void Session::SendRecordedAudio()
        {
			if (!connection_)
				return;

            if (!audio_sending_enabled_)
                return;

            Vector3df avatar_position;
            Vector3df avatar_direction;

            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
            if (!sound_service)
            {
                MumbleVoipModule::LogDebug("Cannot record audio: Soundservice cannot be found.");
                return;
            }

            while (sound_service->GetRecordedSoundSize() > SAMPLES_IN_FRAME*SAMPLE_WIDTH/8)
            {
                int bytes_to_read = SAMPLES_IN_FRAME*SAMPLE_WIDTH/8;
                PCMAudioFrame* frame = new PCMAudioFrame(SAMPLE_RATE, SAMPLE_WIDTH, NUMBER_OF_CHANNELS, bytes_to_read );
                int bytes = sound_service->GetRecordedSoundData(frame->DataPtr(), bytes_to_read);
                assert(bytes_to_read == bytes);

                //if (voice_indicator_)
                //{
                //    voice_indicator_->AnalyzeAudioFrame(frame);
                //    if (!voice_indicator_->IsSpeaking())
                //    {
                //        delete frame;
                //        continue;
                //    }
                //}
                connection_->SendAudioFrame(frame, avatar_position);
//                emit AudioFrameSent(frame);
                delete frame;
            }
        }

        void Session::PlaybackReceivedAudio()
        {
			if (!connection_)
				return;

			if (!audio_sending_enabled_)
				return;

            for(;;)
            {
                AudioPacket packet = connection_->GetAudioPacket();
                if (packet.second == 0)
                    break; // nothing to play anymore

				bool muted = false;
				foreach(Participant* participant, participants_)
				{
					if (participant->UserPtr() == packet.first && participant->IsMuted())
					{
						muted = true;
						break;
					}
				}
				if (!muted)
					PlaybackAudioFrame(packet.first, packet.second);
            }
        }

        void Session::PlaybackAudioFrame(User* user, PCMAudioFrame* frame)
        {
            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = SoundService();
            if (!sound_service.get())
                return;

            Foundation::SoundServiceInterface::SoundBuffer sound_buffer;

            sound_buffer.data_.resize(frame->DataSize());
            memcpy(&sound_buffer.data_[0], frame->DataPtr(), frame->DataSize());

            sound_buffer.frequency_ = frame->SampleRate();
            if (frame->SampleWidth() == 16)
                sound_buffer.sixteenbit_ = true;
            else
                sound_buffer.sixteenbit_ = false;

            if (frame->Channels() == 2)
                sound_buffer.stereo_ = true;
            else
                sound_buffer.stereo_ = false;

            QMutexLocker user_locker(user);
            if (audio_playback_channels_.contains(user->Session()))
                if (user->PositionKnown())
                    sound_service->PlaySoundBuffer3D(sound_buffer, Foundation::SoundServiceInterface::Voice, user->Position(), audio_playback_channels_[user->Session()]);
                else
                    sound_service->PlaySoundBuffer(sound_buffer,  Foundation::SoundServiceInterface::Voice, audio_playback_channels_[user->Session()]);
            else
                if (user->PositionKnown())
                    audio_playback_channels_[user->Session()] = sound_service->PlaySoundBuffer3D(sound_buffer, Foundation::SoundServiceInterface::Voice, user->Position(), 0);
                else
                    audio_playback_channels_[user->Session()] = sound_service->PlaySoundBuffer(sound_buffer,  Foundation::SoundServiceInterface::Voice, 0);

            delete frame;
        }

        boost::shared_ptr<Foundation::SoundServiceInterface> Session::SoundService()
        {
            if (!framework_)
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            Foundation::ServiceManagerPtr service_manager = framework_->GetServiceManager();

            if (!service_manager.get())
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            boost::shared_ptr<Foundation::SoundServiceInterface> sound_service = service_manager->GetService<Foundation::SoundServiceInterface>(Foundation::Service::ST_Sound).lock();

            if (!sound_service.get())
                return boost::shared_ptr<Foundation::SoundServiceInterface>();

            return sound_service;
        }

    } // InWorldVoice

} // MumbleVoip
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_set_homer_bar.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file p9_pm_set_homer_bar.C
/// @brief Setup a PBABAR to locate the HOMER region for the OCC complex

// *HWP HWP Owner       : Amit Kumar <akumar3@us.ibm.com>
// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Bilicon Patil <bilpatil@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : HS
///
///
/// High-level procedure flow:
/// \verbatim
///
///     Address and size of HOMER for the target (chip) is passed based on
///     where the caller has allocated this memory for this target.
///
///     The Base Address and a size mask for the region is passed.  This is
///     used to establish the PBA BAR and mask hardware to set the legal
///     bounds for OCC complex accesses.
///
///     The BAR defines address bits 14:43 in natural bit alignment (eg no
///     shifting)
///
///     The Size (in MB) of the region where region is located.
///         If not a power of two value, the value will be rounded up to the
///         next power of 2 for setting the hardware mask
///
///         If 0 is defined and the BAR is also defined as 0, then the BAR
///         is set (to 0) but no image accessing is done as this is considered
///         a BAR reset condition.
///
///         If 0 is defined and the BAR is NOT 0, an error is returned as this
///         is defining a zero sized, real region.
///
///     Flow (given BAR and Size are ok per the above)
///        Check that passed address is within the 56 bit real address range
///        Check that image address + image size does not extend past the 56 bit
///            boundary
///
///        Call p9_pba_bar_config to set up PBA BAR 0 with the address and
///            size of the HOMER region as passed via calling parameters
///         i_mem_bar and i_mem_size.
///
///  Procedure Prereq:
///     - HOMER memory region has been allocated.
///
///  CQ Class:  power_management
/// \endverbatim
///
//-------------------------------------------------------------------------------

// ------------------------------------------------------------------------------
// Includes
// ------------------------------------------------------------------------------
#include <fapi2.H>
#include "p9_misc_scom_addresses.H"
#include "p9_pm_set_homer_bar.H"
#include "p9_pm.H"
#include "p9_pm_pba_init.H"
#include "p9_pm_pba_bar_config.H"

// ------------------------------------------------------------------------------
// Constant definitions
// ------------------------------------------------------------------------------
static const uint64_t BAR_MASK_4MB_ALIGN = 0x00000000003FFFFFull;

// The value here will yield the appropriate nibble for accessing the PowerBus

enum PBA_BARS
{
    PBA_BAR0    = 0x0,
    PBA_BAR1    = 0x1,
    PBA_BAR2    = 0x2,
    PBA_BAR3    = 0x3
};

// ------------------------------------------------------------------------------
// Function definitions
// ------------------------------------------------------------------------------

/// \param[in] i_target     Procesor Chip target
/// \param[in] i_mem_bar    Base address of the region where image is located
/// \param[in] i_mem_size   Size (in MB) of the region where image is located
///                         if not a power of two value, the value will be
///                         rounded up to the next power of 2 for setting the
///                         hardware mask.  The value of 0 is only legal if
///                         i_mem_bar is also 0;  else an error is indicated.
///
fapi2::ReturnCode
p9_pm_set_homer_bar(  const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
                      const uint64_t i_mem_bar,
                      const uint64_t i_mem_size)
{

    fapi2::ReturnCode    l_rc;
    uint64_t region_masked_address;

    // Hardcoded use of PBA BAR and SCOPE
    //const uint32_t      pba_bar = PBA_BAR0;
    //p9pba::CMD_SCOPE    slw_pba_cmd_scope = p9pba::GROUP;

    FAPI_INF("Entering p9_pm_set_homer_bar ...");

    // Check to make sure mem_bar is also 0 when mem_size is 0.
    FAPI_ASSERT(!((i_mem_size == 0) && (i_mem_bar != 0)),
                fapi2::P9_PM_SET_HOMER_BAR_SIZE_INVALID().set_MEM_BAR(i_mem_bar)
                .set_MEM_SIZE(i_mem_size),
                "ERROR:HOMER Size is 0 but BAR is non-zero:0x%16llx", i_mem_bar);
    // check that bar address passed in 4MB aligned(eg bits 44:63 are zero)

    region_masked_address = i_mem_bar & BAR_MASK_4MB_ALIGN;
    FAPI_ASSERT((region_masked_address == 0),
                fapi2::P9_PM_SET_HOMER_BAR_NOT_4MB_ALIGNED().set_MEM_BAR(i_mem_bar),
                "ERROR: i_mem_bar:0x%16llx is not 4MB aligned ", i_mem_bar);

    FAPI_DBG("Calling pba_bar_config with BAR %x Addr: 0x%16llX  Size: 0x%16llX",
             PBA_BAR0, i_mem_bar, i_mem_size);

    // Set the PBA BAR for the HOMER base
    FAPI_EXEC_HWP(l_rc, p9_pm_pba_bar_config, i_target,
                  PBA_BAR0,
                  i_mem_bar,
                  i_mem_size,
                  p9pba::GROUP, 0);

    fapi2::current_err = l_rc;

fapi_try_exit:
    return fapi2::current_err;

}
<commit_msg>PM Level 3 for multiple procedures<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/pm/p9_pm_set_homer_bar.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file p9_pm_set_homer_bar.C
/// @brief Setup a PBABAR to locate the HOMER region for the OCC complex

// *HWP Owner           :   Greg Still <stillgs@us.ibm.com>
// *HWP Backup Owner    :   Prasad BGR <prasadbgr.in.ibm.com>
// *HWP FW Owner        :   Prem S Jha <premjha2@in.ibm.com>
// *HWP Team            :   PM
// *HWP Level           :   3
// *HWP Consumed by     :   HS
///
///
/// High-level procedure flow:
/// \verbatim
///
///     Address and size of HOMER for the target (chip) is passed based on
///     where the caller has allocated this memory for this target.
///
///     The Base Address and a size mask for the region is passed.  This is
///     used to establish the PBA BAR and mask hardware to set the legal
///     bounds for OCC complex accesses.
///
///     The BAR defines address bits 14:43 in natural bit alignment (eg no
///     shifting)
///
///     The Size (in MB) of the region where region is located.
///         If not a power of two value, the value will be rounded up to the
///         next power of 2 for setting the hardware mask
///
///         If 0 is defined and the BAR is also defined as 0, then the BAR
///         is set (to 0) but no image accessing is done as this is considered
///         a BAR reset condition.
///
///         If 0 is defined and the BAR is NOT 0, an error is returned as this
///         is defining a zero sized, real region.
///
///     Flow (given BAR and Size are ok per the above)
///        Check that passed address is within the 56 bit real address range
///        Check that image address + image size does not extend past the 56 bit
///            boundary
///
///        Call p9_pba_bar_config to set up PBA BAR 0 with the address and
///            size of the HOMER region as passed via calling parameters
///         i_mem_bar and i_mem_size.
///
///  Procedure Prereq:
///     - HOMER memory region has been allocated.
///
///  CQ Class:  power_management
/// \endverbatim
///
//-------------------------------------------------------------------------------

// ------------------------------------------------------------------------------
// Includes
// ------------------------------------------------------------------------------
#include <fapi2.H>
#include "p9_misc_scom_addresses.H"
#include "p9_pm_set_homer_bar.H"
#include "p9_pm.H"
#include "p9_pm_pba_init.H"
#include "p9_pm_pba_bar_config.H"

// ------------------------------------------------------------------------------
// Constant definitions
// ------------------------------------------------------------------------------
static const uint64_t BAR_MASK_4MB_ALIGN = 0x00000000003FFFFFull;

// The value here will yield the appropriate nibble for accessing the PowerBus

enum PBA_BARS
{
    PBA_BAR0    = 0x0,
    PBA_BAR1    = 0x1,
    PBA_BAR2    = 0x2,
    PBA_BAR3    = 0x3
};

// ------------------------------------------------------------------------------
// Function definitions
// ------------------------------------------------------------------------------

/// \param[in] i_target     Procesor Chip target
/// \param[in] i_mem_bar    Base address of the region where image is located
/// \param[in] i_mem_size   Size (in MB) of the region where image is located
///                         if not a power of two value, the value will be
///                         rounded up to the next power of 2 for setting the
///                         hardware mask.  The value of 0 is only legal if
///                         i_mem_bar is also 0;  else an error is indicated.
///
fapi2::ReturnCode
p9_pm_set_homer_bar(  const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
                      const uint64_t i_mem_bar,
                      const uint64_t i_mem_size)
{

    fapi2::ReturnCode    l_rc;
    uint64_t region_masked_address;

    // Hardcoded use of PBA BAR and SCOPE
    //const uint32_t      pba_bar = PBA_BAR0;
    //p9pba::CMD_SCOPE    slw_pba_cmd_scope = p9pba::GROUP;

    FAPI_INF("Entering p9_pm_set_homer_bar ...");

    // Check to make sure mem_bar is also 0 when mem_size is 0.
    FAPI_ASSERT(!((i_mem_size == 0) && (i_mem_bar != 0)),
                fapi2::P9_PM_SET_HOMER_BAR_SIZE_INVALID().set_MEM_BAR(i_mem_bar)
                .set_MEM_SIZE(i_mem_size),
                "ERROR:HOMER Size is 0 but BAR is non-zero:0x%16llx", i_mem_bar);
    // check that bar address passed in 4MB aligned(eg bits 44:63 are zero)

    region_masked_address = i_mem_bar & BAR_MASK_4MB_ALIGN;
    FAPI_ASSERT((region_masked_address == 0),
                fapi2::P9_PM_SET_HOMER_BAR_NOT_4MB_ALIGNED().set_MEM_BAR(i_mem_bar),
                "ERROR: i_mem_bar:0x%16llx is not 4MB aligned ", i_mem_bar);

    FAPI_DBG("Calling pba_bar_config with BAR %x Addr: 0x%16llX  Size: 0x%16llX",
             PBA_BAR0, i_mem_bar, i_mem_size);

    // Set the PBA BAR for the HOMER base
    FAPI_EXEC_HWP(l_rc, p9_pm_pba_bar_config, i_target,
                  PBA_BAR0,
                  i_mem_bar,
                  i_mem_size,
                  p9pba::GROUP, 0);

    fapi2::current_err = l_rc;

fapi_try_exit:
    return fapi2::current_err;

}
<|endoftext|>