<commit_before>
/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000, 2001 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

/****************** <SNX heading BEGIN do not edit this line> *****************
 *
 * Juggler Juggler
 *
 * Original Authors:
 *   Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <SNX heading END do not edit this line> ******************/

// Kevin Meinert
// simple glut skeleton application: look for the !!!TODO!!!s,
//  and fill in your code
//                          there as needed
//

#ifdef WIN32
   #include <windows.h>  // make the app win32 friendly. :)
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <snx/sonix.h>    // interface
#include <snx/SoundHandle.h>
#include "StopWatch.h"

#include <iostream.h>
#include <stdlib.h>

// a place to store application data...
class AppWindow
{
public:
   static int width, height;
   static int mainWin_contextID;
};
int AppWindow::width = 0, AppWindow::height = 0;
int AppWindow::mainWin_contextID = -1;

StopWatch stopWatch;

int soundpos = 0;
float pitchbend = 1.0f;
float cutoff = 0.2f;
float volume = 1.0f;
bool pause_sound = false;
bool retriggerable = false;

// our sound object...
snx::SoundHandle kevinSound;

void drawGrid()
{
   glBegin( GL_LINES );
      for ( int x = -1000; x < 1000; ++x)
      {
         glVertex3f( -1000, 0, x );
         glVertex3f(  1000, 0, x );
         glVertex3f( x, 0, -1000 );
         glVertex3f( x, 0,  1000 );
      }
   glEnd();
}

//////////////////////////////////////////////////
// This is called on a glutPostRedisplay
//////////////////////////////////////////////////
static void OnRedisplay()
{
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
   glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
   glEnable( GL_DEPTH_TEST );
   glEnable( GL_BLEND );
   glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

   // set up the projection matrix
   glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      gluPerspective( 80.0f, AppWindow::width / AppWindow::height, 0.01f, 1000.0f );

   // initialize your matrix stack used for transforming your models
    glMatrixMode( GL_MODELVIEW );
      glLoadIdentity();

   // !!!TODO!!!: replace the following with your own opengl commands!
   glTranslatef( 0, -10, 0 );
   drawGrid();
   // !!!TODO!!!: ////////////////////////////////////////

   // swaps the front and back frame buffers.
   // hint: you've been drawing on the back, offscreen, buffer.
   // This command then brings that framebuffer onscreen.
   glutSwapBuffers();
}

//////////////////////////////////////////////////
// This is called repeatedly, as fast as possible
//////////////////////////////////////////////////
#include "unistd.h"
static void OnIdle()
{
   // According to the GLUT specification, the current window is
   // undefined during an idle callback.  So we need to explicitly change
   // it if necessary
   if ( glutGetWindow() != AppWindow::mainWin_contextID )
      glutSetWindow( AppWindow::mainWin_contextID );

   // tell glut to call redisplay (which then calls OnRedisplay)
   glutPostRedisplay();

   sonix::instance()->step( stopWatch.timeDelta() );
   stopWatch.pulse();
}

/////////////////////////////////////////////
// This is called on a Resize of the glut window
/////////////////////////////////////////////
static void OnReshape( int width, int height )
{
   // save these params in case your app needs them
   AppWindow::width = width;
   AppWindow::height = height;

   // set your viewport to the extents of the window
   glViewport( 0, 0, width, height );

   // let the app run idle, while resizing,
   // glut does not do this for us automatically, so call OnIdle explicitly.
   OnIdle();
}

////////////////////////////////
// This is called on a Down Keypress
////////////////////////////////
static void OnKeyboardDown( unsigned char k, int x, int y )
{
   switch (k)
   {
   // If user pressed 'q' or 'ESC', then exit the app.
   // this is really ungraceful, but necessary since GLUT does a while(1)
   // as it's control loop.  There is no GLUT method to exit, unfortunately.
   case 'q':
   case 27:
      exit( 0 );
      break;
   case '1':
   {
      sonix::instance()->changeAPI( "Stub" );
      snx::SoundInfo si;
      si.filename = "sol.wav";
      si.ambient = false;
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );

      sonix::instance()->changeAPI( "OpenAL" );
   }
   break;
   case '2':
   {
      sonix::instance()->changeAPI( "Stub" );
      snx::SoundInfo si;
      si.filename = "sep.wav";
      si.ambient = false;
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );

      sonix::instance()->changeAPI( "AudioWorks" );
   }
   break;
      case '3':
   {
      sonix::instance()->changeAPI( "Stub" );
   }
   break;
      case 'a':
   {
      snx::SoundInfo si;
      si.ambient = false;
      si.filename = "sol.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      std::cout<<"positional"<<std::endl;
   }
   break;
      case 'b':
   {
      snx::SoundInfo si;
      si.ambient = true;
      si.filename = "sep.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      kevinSound.setAmbient( true );
      std::cout<<"ambient"<<std::endl;
   }
   break;
      case 'c':
   {
      snx::SoundInfo si;
      si.ambient = false;
      si.filename = "suck.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      std::cout<<"positional"<<std::endl;
   }
   break;
   case 't':
   {
      kevinSound.trigger();
   }
   break;
   case 'y':
   {
      kevinSound.trigger( -1 );
   }
   break;
   case 'p':
   {
      pause_sound = !pause_sound;
      if (pause_sound)
         kevinSound.pause();
      else
         kevinSound.unpause();
      std::cout << "paused " << kevinSound.isPaused() << std::endl;
   }
   break;
   case 's':
   {
      kevinSound.stop();
   }
   break;

   case ',':
   {
      soundpos -= 1;
      kevinSound.setPosition( soundpos, 0, 0 );
      std::cout<<"soundpos: "<<soundpos<<std::endl;
   }
   break;

   case 'r':
   {
      retriggerable = !retriggerable;
      kevinSound.setRetriggerable( retriggerable );
      std::cout<<"retriggerable: "<<kevinSound.isRetriggerable()<<std::endl;
   }
   break;

   case '.':
   {
      soundpos += 1;
      kevinSound.setPosition( soundpos, 0, 0 );
      std::cout<<"soundpos: "<<soundpos<<std::endl;
   }
   break;

   case '[':
   {
      pitchbend -= 0.1;
      kevinSound.setPitchBend( pitchbend );
      std::cout<<"pitchbend: "<<pitchbend<<std::endl;
   }
   break;

   case ']':
   {
      pitchbend += 0.1;
      kevinSound.setPitchBend( pitchbend );
      std::cout<<"pitchbend: "<<pitchbend<<std::endl;
   }
   break;

   case ';':
   {
      cutoff -= 0.01;
      kevinSound.setCutoff( cutoff );
      std::cout<<"Cutoff: "<<cutoff<<std::endl;
   }
   break;

   case '\'':
   {
      cutoff += 0.01;
      kevinSound.setCutoff( cutoff );
      std::cout<<"Cutoff: "<<cutoff<<std::endl;
   }
   break;

   case '-':
   {
      volume -= 0.1;
      kevinSound.setVolume( volume );
      std::cout<<"volume: "<<volume<<std::endl;
   }
   break;

   case '=':
   {
      volume += 0.1;
      kevinSound.setVolume( volume );
      std::cout<<"volume: "<<volume<<std::endl;
   }
   break;

   default:
      // do nothing if no key is pressed
      break;
   }
}
////////////////////////////////
// This is called on a Up Keypress
////////////////////////////////
static void OnKeyboardUp( unsigned char k, int x, int y )
{
   switch (k)
   {
   case 'a':
      // !!!TODO!!!: add handler for when UP is released
      break;

   case 'z':
      // !!!TODO!!!: add handler for when DOWN is released
      break;

   default:
      // do nothing if no key is pressed
      break;
   }
}

////////////////////////////////
// This is called on a Down Keypress
// of a "special" key such as the grey arrows.
////////////////////////////////
static void OnSpecialKeyboardDown(int k, int x, int y)
{
   switch (k)
   {
   case GLUT_KEY_UP:
      // !!!TODO!!!: add handler for when UP is pressed
      break;
   case GLUT_KEY_DOWN:
      // !!!TODO!!!: add handler for when DOWN is pressed
      break;
   default:
      // do nothing if no special key pressed
      break;
   }
}

////////////////////////////////
// This is called on a Up Keypress
////////////////////////////////
static void OnSpecialKeyboardUp( int k, int x, int y )
{
   switch (k)
   {
   case GLUT_KEY_UP:
      // !!!TODO!!!: add handler for when UP is released
      break;
   case GLUT_KEY_DOWN:
      // !!!TODO!!!: add handler for when DOWN is released
      break;
   default:
      // do nothing if no special key pressed
      break;
   }
}

////////////////////////////////
// This is called when mouse changes position
// x and y are the screen position
// in your 2D window's coordinate frame
////////////////////////////////
static void OnMousePos( int x, int y )
{
   // !!!TODO!!!: do something based on mouse position
}

////////////////////////////////
// This is called when mouse clicks
////////////////////////////////
static void OnMouseClick( int a, int b, int c, int d )
{
   // !!!TODO!!!: Need mouse interaction?
   //             read the glut docs/manpage to find out how to query
   //             which button was pressed...
   //             you may have to get this from the glut website
   //             (use www.google.com to search for it)
}

// Initialize the application
// initialize the state of your app here if needed...
static void OnApplicationInit()
{
   // Don't put open GL code here, this func may be called at anytime
   // even before the API is initialized
   // (like before a graphics context is obtained)

   kevinSound.init( "kevin" );
   stopWatch.pulse();
}

int main(int argc, char* argv[])
{
    // Initialize the application
    // initialize the state of your app here if needed...
    OnApplicationInit();

    // Set the window's initial size
    ::glutInitWindowSize( 640, 480 );
    ::glutInit( &argc, argv );

    // Set to double buffer to reduce flicker
    ::glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );

    // Set the window title
    AppWindow::mainWin_contextID = ::glutCreateWindow( "GLUT application" );

    cout<<"\n"<<flush;
    cout<<"sonix sample OpenGL+sound app - by kevin - kevn@vrjuggler.org\n"<<flush;
    cout<<"       usage:  t - trigger single shot sound\n"<<flush;
    cout<<"               y - trigger infinitly looping sound\n"<<flush;
    cout<<"               p - pause/unpause sound\n"<<flush;
    cout<<"               s - stop sound\n"<<flush;
    cout<<"               r - toggle isRetriggerable\n"<<flush;
    cout<<"               - - volume decrement\n"<<flush;
    cout<<"               = - volume increment\n"<<flush;
    cout<<"               [ - pitch decrement\n"<<flush;
    cout<<"               ] - pitch increment\n"<<flush;
    cout<<"               ; - lowpass filter cutoff decrement\n"<<flush;
    cout<<"               ' - lowpass filter cutoff increment\n"<<flush;
    cout<<"               , - move 3d sound source to the left\n"<<flush;
    cout<<"               . - move 3d sound source to the right\n"<<flush;
    cout<<"               1 - Change subsystem to OpenAL\n"<<flush;
    cout<<"               2 - Change subsystem to AudioWorks\n"<<flush;
    cout<<"               3 - Change subsystem to None\n"<<flush;
    cout<<"               a - configure sound object to sol.wav\n"<<flush;
    cout<<"               b - configure sound object to drumsolo.wav\n"<<flush;
    cout<<"               c - configure sound object to suck.wav\n"<<flush;
    cout<<"\n"<<flush;

   // display callbacks.
   ::glutReshapeFunc( OnReshape );
   ::glutIdleFunc( OnIdle );
   ::glutDisplayFunc( OnRedisplay );

   // tell glut to not call the keyboard callback repeatedly
   // when holding down a key. (uses edge triggering, like the mouse)
   ::glutIgnoreKeyRepeat( 1 );

   // keyboard callback functions.
   ::glutKeyboardFunc( OnKeyboardDown );
   ::glutKeyboardUpFunc( OnKeyboardUp );
   ::glutSpecialFunc( OnSpecialKeyboardDown );
   ::glutSpecialUpFunc( OnSpecialKeyboardUp );

   // mouse callback functions...
   ::glutMouseFunc( OnMouseClick );
   ::glutMotionFunc( OnMousePos );
   ::glutPassiveMotionFunc( OnMousePos );

    // start the application loop, your callbacks will now be called
    // time for glut to sit and spin.
    ::glutMainLoop();

    return 1;
}

<commit_msg>added subsynth<commit_after>
/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998, 1999, 2000, 2001 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

/****************** <SNX heading BEGIN do not edit this line> *****************
 *
 * Juggler Juggler
 *
 * Original Authors:
 *   Kevin Meinert
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <SNX heading END do not edit this line> ******************/

// Kevin Meinert
// simple glut skeleton application: look for the !!!TODO!!!s,
//  and fill in your code
//                          there as needed
//

#ifdef WIN32
   #include <windows.h>  // make the app win32 friendly. :)
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <snx/sonix.h>    // interface
#include <snx/SoundHandle.h>
#include "StopWatch.h"

#include <iostream.h>
#include <stdlib.h>

// a place to store application data...
class AppWindow
{
public:
   static int width, height;
   static int mainWin_contextID;
};
int AppWindow::width = 0, AppWindow::height = 0;
int AppWindow::mainWin_contextID = -1;

StopWatch stopWatch;

int soundpos = 0;
float pitchbend = 1.0f;
float cutoff = 0.2f;
float volume = 1.0f;
bool pause_sound = false;
bool retriggerable = false;

// our sound object...
snx::SoundHandle kevinSound;

void drawGrid()
{
   glBegin( GL_LINES );
      for ( int x = -1000; x < 1000; ++x)
      {
         glVertex3f( -1000, 0, x );
         glVertex3f(  1000, 0, x );
         glVertex3f( x, 0, -1000 );
         glVertex3f( x, 0,  1000 );
      }
   glEnd();
}

//////////////////////////////////////////////////
// This is called on a glutPostRedisplay
//////////////////////////////////////////////////
static void OnRedisplay()
{
   glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
   glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
   glEnable( GL_DEPTH_TEST );
   glEnable( GL_BLEND );
   glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

   // set up the projection matrix
   glMatrixMode( GL_PROJECTION );
      glLoadIdentity();
      gluPerspective( 80.0f, AppWindow::width / AppWindow::height, 0.01f, 1000.0f );

   // initialize your matrix stack used for transforming your models
    glMatrixMode( GL_MODELVIEW );
      glLoadIdentity();

   // !!!TODO!!!: replace the following with your own opengl commands!
   glTranslatef( 0, -10, 0 );
   drawGrid();
   // !!!TODO!!!: ////////////////////////////////////////

   // swaps the front and back frame buffers.
   // hint: you've been drawing on the back, offscreen, buffer.
   // This command then brings that framebuffer onscreen.
   glutSwapBuffers();
}

//////////////////////////////////////////////////
// This is called repeatedly, as fast as possible
//////////////////////////////////////////////////
#include "unistd.h"
static void OnIdle()
{
   // According to the GLUT specification, the current window is
   // undefined during an idle callback.  So we need to explicitly change
   // it if necessary
   if ( glutGetWindow() != AppWindow::mainWin_contextID )
      glutSetWindow( AppWindow::mainWin_contextID );

   // tell glut to call redisplay (which then calls OnRedisplay)
   glutPostRedisplay();

   sonix::instance()->step( stopWatch.timeDelta() );
   stopWatch.pulse();
}

/////////////////////////////////////////////
// This is called on a Resize of the glut window
/////////////////////////////////////////////
static void OnReshape( int width, int height )
{
   // save these params in case your app needs them
   AppWindow::width = width;
   AppWindow::height = height;

   // set your viewport to the extents of the window
   glViewport( 0, 0, width, height );

   // let the app run idle, while resizing,
   // glut does not do this for us automatically, so call OnIdle explicitly.
   OnIdle();
}

////////////////////////////////
// This is called on a Down Keypress
////////////////////////////////
static void OnKeyboardDown( unsigned char k, int x, int y )
{
   switch (k)
   {
   // If user pressed 'q' or 'ESC', then exit the app.
   // this is really ungraceful, but necessary since GLUT does a while(1)
   // as it's control loop.  There is no GLUT method to exit, unfortunately.
   case 'q':
   case 27:
      exit( 0 );
      break;
   case '1':
   {
      sonix::instance()->changeAPI( "Stub" );
      snx::SoundInfo si;
      si.filename = "sol.wav";
      si.ambient = false;
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );

      sonix::instance()->changeAPI( "OpenAL" );
   }
   break;
   case '2':
   {
      sonix::instance()->changeAPI( "Stub" );
      snx::SoundInfo si;
      si.filename = "sep.wav";
      si.ambient = false;
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );

      sonix::instance()->changeAPI( "AudioWorks" );
   }
   break;
   case '3':
   {
      sonix::instance()->changeAPI( "Stub" );
      snx::SoundInfo si;
      si.filename = "attack.wav";
      si.ambient = false;
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );

      sonix::instance()->changeAPI( "Subsynth" );
   }
   case '4':
   {
      sonix::instance()->changeAPI( "Stub" );
   }
   break;
      case 'a':
   {
      snx::SoundInfo si;
      si.ambient = false;
      si.filename = "sol.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      std::cout<<"positional"<<std::endl;
   }
   break;
      case 'b':
   {
      snx::SoundInfo si;
      si.ambient = true;
      si.filename = "sep.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      kevinSound.setAmbient( true );
      std::cout<<"ambient"<<std::endl;
   }
   break;
      case 'c':
   {
      snx::SoundInfo si;
      si.ambient = false;
      si.filename = "suck.wav";
      si.datasource = snx::SoundInfo::FILESYSTEM;
      kevinSound.configure( si );
      std::cout<<"positional"<<std::endl;
   }
   break;
   case 't':
   {
      kevinSound.trigger();
   }
   break;
   case 'y':
   {
      kevinSound.trigger( -1 );
   }
   break;
   case 'p':
   {
      pause_sound = !pause_sound;
      if (pause_sound)
         kevinSound.pause();
      else
         kevinSound.unpause();
      std::cout << "paused " << kevinSound.isPaused() << std::endl;
   }
   break;
   case 's':
   {
      kevinSound.stop();
   }
   break;

   case ',':
   {
      soundpos -= 1;
      kevinSound.setPosition( soundpos, 0, 0 );
      std::cout<<"soundpos: "<<soundpos<<std::endl;
   }
   break;

   case 'r':
   {
      retriggerable = !retriggerable;
      kevinSound.setRetriggerable( retriggerable );
      std::cout<<"retriggerable: "<<kevinSound.isRetriggerable()<<std::endl;
   }
   break;

   case '.':
   {
      soundpos += 1;
      kevinSound.setPosition( soundpos, 0, 0 );
      std::cout<<"soundpos: "<<soundpos<<std::endl;
   }
   break;

   case '[':
   {
      pitchbend -= 0.1;
      kevinSound.setPitchBend( pitchbend );
      std::cout<<"pitchbend: "<<pitchbend<<std::endl;
   }
   break;

   case ']':
   {
      pitchbend += 0.1;
      kevinSound.setPitchBend( pitchbend );
      std::cout<<"pitchbend: "<<pitchbend<<std::endl;
   }
   break;

   case ';':
   {
      cutoff -= 0.01;
      kevinSound.setCutoff( cutoff );
      std::cout<<"Cutoff: "<<cutoff<<std::endl;
   }
   break;

   case '\'':
   {
      cutoff += 0.01;
      kevinSound.setCutoff( cutoff );
      std::cout<<"Cutoff: "<<cutoff<<std::endl;
   }
   break;

   case '-':
   {
      volume -= 0.1;
      kevinSound.setVolume( volume );
      std::cout<<"volume: "<<volume<<std::endl;
   }
   break;

   case '=':
   {
      volume += 0.1;
      kevinSound.setVolume( volume );
      std::cout<<"volume: "<<volume<<std::endl;
   }
   break;

   default:
      // do nothing if no key is pressed
      break;
   }
}
////////////////////////////////
// This is called on a Up Keypress
////////////////////////////////
static void OnKeyboardUp( unsigned char k, int x, int y )
{
   switch (k)
   {
   case 'a':
      // !!!TODO!!!: add handler for when UP is released
      break;

   case 'z':
      // !!!TODO!!!: add handler for when DOWN is released
      break;

   default:
      // do nothing if no key is pressed
      break;
   }
}

////////////////////////////////
// This is called on a Down Keypress
// of a "special" key such as the grey arrows.
////////////////////////////////
static void OnSpecialKeyboardDown(int k, int x, int y)
{
   switch (k)
   {
   case GLUT_KEY_UP:
      // !!!TODO!!!: add handler for when UP is pressed
      break;
   case GLUT_KEY_DOWN:
      // !!!TODO!!!: add handler for when DOWN is pressed
      break;
   default:
      // do nothing if no special key pressed
      break;
   }
}

////////////////////////////////
// This is called on a Up Keypress
////////////////////////////////
static void OnSpecialKeyboardUp( int k, int x, int y )
{
   switch (k)
   {
   case GLUT_KEY_UP:
      // !!!TODO!!!: add handler for when UP is released
      break;
   case GLUT_KEY_DOWN:
      // !!!TODO!!!: add handler for when DOWN is released
      break;
   default:
      // do nothing if no special key pressed
      break;
   }
}

////////////////////////////////
// This is called when mouse changes position
// x and y are the screen position
// in your 2D window's coordinate frame
////////////////////////////////
static void OnMousePos( int x, int y )
{
   // !!!TODO!!!: do something based on mouse position
}

////////////////////////////////
// This is called when mouse clicks
////////////////////////////////
static void OnMouseClick( int a, int b, int c, int d )
{
   // !!!TODO!!!: Need mouse interaction?
   //             read the glut docs/manpage to find out how to query
   //             which button was pressed...
   //             you may have to get this from the glut website
   //             (use www.google.com to search for it)
}

// Initialize the application
// initialize the state of your app here if needed...
static void OnApplicationInit()
{
   // Don't put open GL code here, this func may be called at anytime
   // even before the API is initialized
   // (like before a graphics context is obtained)

   kevinSound.init( "kevin" );
   stopWatch.pulse();
}

int main(int argc, char* argv[])
{
    // Initialize the application
    // initialize the state of your app here if needed...
    OnApplicationInit();

    // Set the window's initial size
    ::glutInitWindowSize( 640, 480 );
    ::glutInit( &argc, argv );

    // Set to double buffer to reduce flicker
    ::glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );

    // Set the window title
    AppWindow::mainWin_contextID = ::glutCreateWindow( "GLUT application" );

    cout<<"\n"<<flush;
    cout<<"sonix sample OpenGL+sound app - by kevin - kevn@vrjuggler.org\n"<<flush;
    cout<<"       usage:  t - trigger single shot sound\n"<<flush;
    cout<<"               y - trigger infinitly looping sound\n"<<flush;
    cout<<"               p - pause/unpause sound\n"<<flush;
    cout<<"               s - stop sound\n"<<flush;
    cout<<"               r - toggle isRetriggerable\n"<<flush;
    cout<<"               - - volume decrement\n"<<flush;
    cout<<"               = - volume increment\n"<<flush;
    cout<<"               [ - pitch decrement\n"<<flush;
    cout<<"               ] - pitch increment\n"<<flush;
    cout<<"               ; - lowpass filter cutoff decrement\n"<<flush;
    cout<<"               ' - lowpass filter cutoff increment\n"<<flush;
    cout<<"               , - move 3d sound source to the left\n"<<flush;
    cout<<"               . - move 3d sound source to the right\n"<<flush;
    cout<<"               1 - Change subsystem to OpenAL\n"<<flush;
    cout<<"               2 - Change subsystem to AudioWorks\n"<<flush;
    cout<<"               3 - Change subsystem to None\n"<<flush;
    cout<<"               a - configure sound object to sol.wav\n"<<flush;
    cout<<"               b - configure sound object to drumsolo.wav\n"<<flush;
    cout<<"               c - configure sound object to suck.wav\n"<<flush;
    cout<<"\n"<<flush;

   // display callbacks.
   ::glutReshapeFunc( OnReshape );
   ::glutIdleFunc( OnIdle );
   ::glutDisplayFunc( OnRedisplay );

   // tell glut to not call the keyboard callback repeatedly
   // when holding down a key. (uses edge triggering, like the mouse)
   ::glutIgnoreKeyRepeat( 1 );

   // keyboard callback functions.
   ::glutKeyboardFunc( OnKeyboardDown );
   ::glutKeyboardUpFunc( OnKeyboardUp );
   ::glutSpecialFunc( OnSpecialKeyboardDown );
   ::glutSpecialUpFunc( OnSpecialKeyboardUp );

   // mouse callback functions...
   ::glutMouseFunc( OnMouseClick );
   ::glutMotionFunc( OnMousePos );
   ::glutPassiveMotionFunc( OnMousePos );

    // start the application loop, your callbacks will now be called
    // time for glut to sit and spin.
    ::glutMainLoop();

    return 1;
}

<|endoftext|>


<commit_before>#include <iostream>

#include <SFML/Network/Packet.hpp>

#include "shared/network/MessageData.h"
#include "shared/network/UtilsNetwork.h"
#include "shared/network/MsgFactory.h"

#include "client/network/ClientMsgQueue.h"
#include "client/network/ClientTCPManager.h"

ClientTCPManager::ClientTCPManager(ClientMsgQueue& msgQueue)
: m_msgQueue(msgQueue)
, m_threadReceiver(nullptr) {
    m_socket.setBlocking(true);
}

ClientTCPManager::~ClientTCPManager() {
    delete m_threadReceiver;
}

bool ClientTCPManager::connect(sf::IpAddress serverAdress, unsigned short serverPortTcp, sf::Time timeout) {
    std::cout << "[Conn][TCP] \tTry to establish connection with server" << std::endl;
    sf::Socket::Status status = m_socket.connect(serverAdress, serverPortTcp, timeout);
    return (status == sf::Socket::Done);
}

void ClientTCPManager::disconnect() {
    m_socket.disconnect();
}

void ClientTCPManager::startReceiverThread() {
    m_threadReceiver = new std::thread(&ClientTCPManager::receiver, this);
}

void ClientTCPManager::receiver() {
    while (true) {
        MessageData* msg = new MessageData();
        m_socket.receive(*msg);
        m_msgQueue.push(msg);
    }
}

bool ClientTCPManager::send(MessageData& message) const {
    std::cout << "[Send][TCP] \t" /*<< message.getType()*/ << std::endl;
    return (m_socket.send(message) == sf::Socket::Done);
}
<commit_msg>Manage receive status in ClientTCP <commit_after>#include <iostream>

#include <SFML/Network/Packet.hpp>

#include "shared/network/MessageData.h"
#include "shared/network/UtilsNetwork.h"
#include "shared/network/MsgFactory.h"

#include "client/network/ClientMsgQueue.h"
#include "client/network/ClientTCPManager.h"

ClientTCPManager::ClientTCPManager(ClientMsgQueue& msgQueue)
: m_msgQueue(msgQueue)
, m_threadReceiver(nullptr) {
    m_socket.setBlocking(true);
}

ClientTCPManager::~ClientTCPManager() {
    delete m_threadReceiver;
}

bool ClientTCPManager::connect(sf::IpAddress serverAdress, unsigned short serverPortTcp, sf::Time timeout) {
    std::cout << "[Conn][TCP] \tTry to establish connection with server" << std::endl;
    sf::Socket::Status status = m_socket.connect(serverAdress, serverPortTcp, timeout);
    return (status == sf::Socket::Done);
}

void ClientTCPManager::disconnect() {
    m_socket.disconnect();
}

void ClientTCPManager::startReceiverThread() {
    m_threadReceiver = new std::thread(&ClientTCPManager::receiver, this);
}

void ClientTCPManager::receiver() {
    while (true) {
        MessageData* msg = new MessageData();
        switch (m_socket.receive(*msg)) {
            case sf::Socket::Status::Done:
            {
                m_msgQueue.push(msg);
            }
                break;
            case sf::Socket::Status::Disconnected:
            {
                // @TODO
                std::cout << "[TCP][Recv] \t TCP Server connection disconnected" << std::endl;
                exit(-1);
            }
                break;
            case sf::Socket::Status::Error:
            {
                std::cout << "[TCP][Recv] \t TCP receive error" << std::endl;
            }
                break;
            default :
                std::cout << "[TCP][Recv] \t TCP Unknow status error" << std::endl;
        }
    }
}

bool ClientTCPManager::send(MessageData& message) const {
    std::cout << "[Send][TCP] \t" /*<< message.getType()*/ << std::endl;
    return (m_socket.send(message) == sf::Socket::Done);
}
<|endoftext|>


<commit_before>#include <iostream>

#include <QtGui>
#include<QMessageBox>

#include "zjsonobject.h"
#include "zjsonparser.h"
#include "zstring.h"

#include "flyembodyinfodialog.h"
#include "ui_flyembodyinfodialog.h"

/*
 * this dialog displays a list of bodies and their properties; data is
 * loaded from a static json bookmarks file
 *
 * djo, 7/15
 *
 */
FlyEmBodyInfoDialog::FlyEmBodyInfoDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::FlyEmBodyInfoDialog)
{
    ui->setupUi(this);
    connect(ui->openButton, SIGNAL(clicked()), this, SLOT(onOpenButton()));
    connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(onCloseButton()));

    m_model = createModel(ui->tableView);
    ui->tableView->setModel(m_model);

}

QStandardItemModel* FlyEmBodyInfoDialog::createModel(QObject* parent) {
    QStandardItemModel* model = new QStandardItemModel(0, 3, parent);
    setHeaders(model);
    return model;
}

void FlyEmBodyInfoDialog::setHeaders(QStandardItemModel * model) {
    model->setHorizontalHeaderItem(0, new QStandardItem(QString("Body ID")));
    model->setHorizontalHeaderItem(1, new QStandardItem(QString("# synapses")));
    model->setHorizontalHeaderItem(2, new QStandardItem(QString("status")));
}

void FlyEmBodyInfoDialog::importBookmarksFile(QString filename) {
    ZJsonObject jsonObject;

    if (!jsonObject.load(filename.toStdString())) {
        QMessageBox errorBox;
        errorBox.setText("Problem parsing json file");
        errorBox.setInformativeText("Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return;
    }

    if (!isValidBookmarkFile(jsonObject)) {
        return;
    }

    // update model from the object, or the data piece of it
    ZJsonValue dataObject = jsonObject.value("data");
    updateModel(dataObject);

}

bool FlyEmBodyInfoDialog::isValidBookmarkFile(ZJsonObject jsonObject) {
    // validation is admittedly limited for now; ultimately, I
    //  expect we'll be getting the info from DVID rather than
    //  a file anyway, so I'm not going to spend much time on it

    // likewise, I'm copy/pasting the error dialog code rather than
    //  neatly factoring it out

    QMessageBox errorBox;
    if (!jsonObject.hasKey("data") || !jsonObject.hasKey("metadata")) {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This file is missing 'data' or 'metadata'. Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    ZJsonObject metadata = (ZJsonObject) jsonObject.value("metadata");
    if (!metadata.hasKey("description")) {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This file is 'metadata/description'. Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    ZString description = ZJsonParser::stringValue(metadata["description"]);
    if (description != "bookmarks") {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This json file does not have description 'bookmarks'!");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    return true;
}

void FlyEmBodyInfoDialog::onCloseButton() {
    close();
}

void FlyEmBodyInfoDialog::onOpenButton() {
    QString filename = QFileDialog::getOpenFileName(this, "Open bookmarks file");
    if (!filename.isEmpty()) {
        importBookmarksFile(filename);
    }
}

void FlyEmBodyInfoDialog::updateModel(ZJsonValue data) {
    if (!data.isArray()) {
        // move to validation step?  we don't check that
        //  elements are actually bookmarks, either
        std::cout << "data is not an array?" << std::endl;
        return;
    }

    // clear model, then load new data
    m_model->clear();
    setHeaders(m_model);

    ZJsonArray bookmarks(data);
    m_model->setRowCount(bookmarks.size());
    for (size_t i = 0; i < bookmarks.size(); ++i) {
        ZJsonObject bkmk(bookmarks.at(i), false);

        // carefully set data for items so they will sort numerically;
        //  compare the "body status" entry, which we want as a string
        int bodyID = ZJsonParser::integerValue(bkmk["body ID"]);
        QStandardItem * bodyIDItem = new QStandardItem();
        bodyIDItem->setData(QVariant(bodyID), Qt::DisplayRole);
        m_model->setItem(i, 0, bodyIDItem);

        int nSynapses = ZJsonParser::integerValue(bkmk["body synapses"]);
        QStandardItem * synapsesItem = new QStandardItem();
        synapsesItem->setData(QVariant(nSynapses), Qt::DisplayRole);
        m_model->setItem(i, 1, synapsesItem);

        const char* status = ZJsonParser::stringValue(bkmk["body status"]);
        m_model->setItem(i, 2, new QStandardItem(QString(status)));
    }
    ui->tableView->resizeColumnsToContents();

}

FlyEmBodyInfoDialog::~FlyEmBodyInfoDialog()
{
    delete ui;
}
<commit_msg>set initial sort order<commit_after>#include <iostream>

#include <QtGui>
#include<QMessageBox>

#include "zjsonobject.h"
#include "zjsonparser.h"
#include "zstring.h"

#include "flyembodyinfodialog.h"
#include "ui_flyembodyinfodialog.h"

/*
 * this dialog displays a list of bodies and their properties; data is
 * loaded from a static json bookmarks file
 *
 * djo, 7/15
 *
 */
FlyEmBodyInfoDialog::FlyEmBodyInfoDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::FlyEmBodyInfoDialog)
{
    ui->setupUi(this);
    connect(ui->openButton, SIGNAL(clicked()), this, SLOT(onOpenButton()));
    connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(onCloseButton()));

    m_model = createModel(ui->tableView);
    ui->tableView->setModel(m_model);

}

QStandardItemModel* FlyEmBodyInfoDialog::createModel(QObject* parent) {
    QStandardItemModel* model = new QStandardItemModel(0, 3, parent);
    setHeaders(model);
    return model;
}

void FlyEmBodyInfoDialog::setHeaders(QStandardItemModel * model) {
    model->setHorizontalHeaderItem(0, new QStandardItem(QString("Body ID")));
    model->setHorizontalHeaderItem(1, new QStandardItem(QString("# synapses")));
    model->setHorizontalHeaderItem(2, new QStandardItem(QString("status")));
}

void FlyEmBodyInfoDialog::importBookmarksFile(QString filename) {
    ZJsonObject jsonObject;

    if (!jsonObject.load(filename.toStdString())) {
        QMessageBox errorBox;
        errorBox.setText("Problem parsing json file");
        errorBox.setInformativeText("Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return;
    }

    if (!isValidBookmarkFile(jsonObject)) {
        return;
    }

    // update model from the object, or the data piece of it
    ZJsonValue dataObject = jsonObject.value("data");
    updateModel(dataObject);

}

bool FlyEmBodyInfoDialog::isValidBookmarkFile(ZJsonObject jsonObject) {
    // validation is admittedly limited for now; ultimately, I
    //  expect we'll be getting the info from DVID rather than
    //  a file anyway, so I'm not going to spend much time on it

    // likewise, I'm copy/pasting the error dialog code rather than
    //  neatly factoring it out

    QMessageBox errorBox;
    if (!jsonObject.hasKey("data") || !jsonObject.hasKey("metadata")) {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This file is missing 'data' or 'metadata'. Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    ZJsonObject metadata = (ZJsonObject) jsonObject.value("metadata");
    if (!metadata.hasKey("description")) {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This file is 'metadata/description'. Are you sure this is a Fly EM JSON file?");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    ZString description = ZJsonParser::stringValue(metadata["description"]);
    if (description != "bookmarks") {
        errorBox.setText("Problem with json file");
        errorBox.setInformativeText("This json file does not have description 'bookmarks'!");
        errorBox.setStandardButtons(QMessageBox::Ok);
        errorBox.setIcon(QMessageBox::Warning);
        errorBox.exec();
        return false;
    }

    return true;
}

void FlyEmBodyInfoDialog::onCloseButton() {
    close();
}

void FlyEmBodyInfoDialog::onOpenButton() {
    QString filename = QFileDialog::getOpenFileName(this, "Open bookmarks file");
    if (!filename.isEmpty()) {
        importBookmarksFile(filename);
    }
}

void FlyEmBodyInfoDialog::updateModel(ZJsonValue data) {
    if (!data.isArray()) {
        // move to validation step?  we don't check that
        //  elements are actually bookmarks, either
        std::cout << "data is not an array?" << std::endl;
        return;
    }

    // clear model, then load new data
    m_model->clear();
    setHeaders(m_model);

    ZJsonArray bookmarks(data);
    m_model->setRowCount(bookmarks.size());
    for (size_t i = 0; i < bookmarks.size(); ++i) {
        ZJsonObject bkmk(bookmarks.at(i), false);

        // carefully set data for items so they will sort numerically;
        //  compare the "body status" entry, which we want as a string
        int bodyID = ZJsonParser::integerValue(bkmk["body ID"]);
        QStandardItem * bodyIDItem = new QStandardItem();
        bodyIDItem->setData(QVariant(bodyID), Qt::DisplayRole);
        m_model->setItem(i, 0, bodyIDItem);

        int nSynapses = ZJsonParser::integerValue(bkmk["body synapses"]);
        QStandardItem * synapsesItem = new QStandardItem();
        synapsesItem->setData(QVariant(nSynapses), Qt::DisplayRole);
        m_model->setItem(i, 1, synapsesItem);

        const char* status = ZJsonParser::stringValue(bkmk["body status"]);
        m_model->setItem(i, 2, new QStandardItem(QString(status)));
    }
    ui->tableView->resizeColumnsToContents();

    // initial sort order is by synapses, descending
    ui->tableView->sortByColumn(1, Qt::DescendingOrder);

}

FlyEmBodyInfoDialog::~FlyEmBodyInfoDialog()
{
    delete ui;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/nest/p10_rng_init_phase2.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 p10_rng_init_phase2.C
/// @brief Perform NX RNG Phase 2 initialization (FAPI2)
///

//
// *HWP HWP Owner: Nicholas Landi <nlandi@ibm.com>
// *HWP FW Owner: Ilya Smirnov <ismirno@us.ibm.com>
// *HWP Consumed by: Cronus, HB
//

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p10_rng_init_phase2.H>
//#include <p10_misc_scom_addresses.H>
//#include <p10_misc_scom_addresses_fld.H>
#include <p10_fbc_utils.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------

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

fapi2::ReturnCode
p10_rng_init_phase2(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("Start");
    fapi2::buffer<uint64_t> l_rng_cfg_data;
    fapi2::buffer<uint64_t> l_rng_bar_data;
    fapi2::buffer<uint64_t> l_rng_failed_int_data;
    fapi2::buffer<uint64_t> l_security_switch_data;

//    uint16_t l_rng_cfg_self_test_hard_fail_status = 0;
    uint8_t  l_nx_rng_bar_enable = 0;
    uint64_t l_nx_rng_bar_addr = 0;
    uint64_t l_nx_rng_bar_base_addr_offset = 0;
    uint8_t  l_nx_rng_failed_int_enable = 0;
    uint64_t l_nx_rng_failed_int_addr = 0;
    std::vector<uint64_t> l_base_addr_nm0, l_base_addr_nm1, l_base_addr_m;
    uint64_t l_base_addr_mmio;

    // 5. RNG is allowed to run for M cycles (M = enough time to complete init;
    // recommend 1 second of time).
    // NOTE: accomplished by delay in execution time between phase1/phase2 HWPs

    //FAPI_TRY(fapi2::getScom(i_target, PU_NX_RNG_CFG, l_rng_cfg_data),
    //         "Error from getScom (NX RNG Status and Control Register)");

    // 6. Host boot checks RNG fail bits again and if a fail is detected
    // then RNG is declared broken

    FAPI_DBG("Checking RNG fail status...");
    // exit if failure is reported in self test hard fail status field
    //l_rng_cfg_data.extractToRight<PU_NX_RNG_CFG_FAIL_REG,
    //                              PU_NX_RNG_CFG_FAIL_REG_LEN>(l_rng_cfg_self_test_hard_fail_status);
    //FAPI_ASSERT(!l_rng_cfg_self_test_hard_fail_status,
    //            fapi2::P10_RNG_INIT_SELF_TEST_FAILED_ERR().
    //            set_TARGET(i_target).
    //            set_SELF_TEST_HARD_FAIL_STATUS(l_rng_cfg_self_test_hard_fail_status),
    //            "Self test hard fail status indicates failure");

    // 7. Host boot maps RNG BARs (see Section 5.31 RNG BAR on page 185).
    // • NX RNG BAR (not mapped/enabled if RNG is broken)
    // • NCU RNG BAR (always mapped to good RNG)
    // • NX RNG Fail Interrupt Addres

    // self test indicates no hard fail
    // if instructed to map the BAR:
    // - enable NX RNG MMIO BAR and get the bar address attributes
    // - optionally map NX RNG failed interrupt address
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_ENABLE,
                           i_target,
                           l_nx_rng_bar_enable),
             "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_ENABLE)");

    //FAPI_TRY(p10_fbc_utils_get_chip_base_address(i_target,
    //         EFF_FBC_GRP_CHIP_IDS,
    //         l_base_addr_nm0,
    //         l_base_addr_nm1,
    //         l_base_addr_m,
    //         l_base_addr_mmio),
    //         "Error from p10_fbc_utils_get_chip_base_address");

    // get RNG BAR addr
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_BASE_ADDR_OFFSET,
                           i_target.getParent<fapi2::TARGET_TYPE_SYSTEM>(),
                           l_nx_rng_bar_base_addr_offset),
             "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_BASE_ADDR_OFFSET)");

    // caculate the NX RNG BAR ADDR based on the bar adddr offset
    l_nx_rng_bar_addr = l_base_addr_mmio;
    l_nx_rng_bar_addr += l_nx_rng_bar_base_addr_offset;

    if (l_nx_rng_bar_enable == fapi2::ENUM_ATTR_PROC_NX_RNG_BAR_ENABLE_ENABLE)
    {
        // map NX RNG MMIO BAR
        //l_rng_bar_data.setBit<PU_NX_MMIO_BAR_ENABLE>();
        //l_rng_bar_data.insert<PU_NX_MMIO_BAR_BAR,
        //                      PU_NX_MMIO_BAR_BAR_LEN, PU_NX_MMIO_BAR_BAR>(l_nx_rng_bar_addr);
        //FAPI_TRY(fapi2::putScom(i_target, PU_NX_MMIO_BAR, l_rng_bar_data),
        //         "Error from putScom (PU_NX_MMIO_BAR)");

        // map NX RNG failed interrupt address
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ENABLE,
                               i_target,
                               l_nx_rng_failed_int_enable),
                 "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ENABLE)");
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ADDR,
                               i_target,
                               l_nx_rng_failed_int_addr),
                 "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ADDR)");

        //if (l_nx_rng_failed_int_enable ==
        //    fapi2::ENUM_ATTR_PROC_NX_RNG_FAILED_INT_ENABLE_ENABLE)
        //{
        //    //l_rng_failed_int_data.setBit<PU_RNG_FAILED_INT_ENABLE>();
        //    //l_rng_failed_int_data.insert<PU_RNG_FAILED_INT_ADDRESS,
        //    //                             PU_RNG_FAILED_INT_ADDRESS_LEN, PU_RNG_FAILED_INT_ADDRESS>
        //    //                             (l_nx_rng_failed_int_addr);

        //    //FAPI_TRY(fapi2::putScom(i_target,
        //    //                        PU_RNG_FAILED_INT,
        //    //                        l_rng_failed_int_data),
        //    //         "Error from putScom (NX RNG Failed Interrupt Address Register");
        //}
        //else
        //{
        //    FAPI_DBG("Skipping setup of NX RNG Failed Interrupt Address Register");
        //}
    }
    else
    {
        FAPI_DBG("Skipping NX RNG BAR programming!");
    }

    // set NX RNG enable
    //l_rng_cfg_data.setBit<PU_NX_RNG_CFG_ENABLE>();
    //FAPI_TRY(fapi2::putScom(i_target, PU_NX_RNG_CFG, l_rng_cfg_data),
    //         "Error from putScom (NX RNG Status and Control Register)");

    // 8. Host boot sets the NX “sticky bit” that asserts
    // tc_nx_block_rng_scom_wr. If tc_nx_block_rng_scom_wr = 1 writes to RNG
    // SCOM register addresses 32 - 38 and 40 are blocked. An attempted
    // write sets Power-Bus Interface FIR Data Register[Write to RNG SCOM
    // reg detected when writes disabled].

    // set NX sticky bit to block future RNG SCOM writes
    // (tc_nx_block_rng_scom_wr)
    //FAPI_TRY(fapi2::getScom(i_target,
    //                        PU_SECURITY_SWITCH_REGISTER_SCOM,
    //                        l_security_switch_data),
    //         "Error from getScom (Security Switch Register");

    //l_security_switch_data.setBit<PU_SECURITY_SWITCH_REGISTER_NX_RAND_NUM_GEN_LOCK>();

    //FAPI_TRY(fapi2::putScom(i_target,
    //                        PU_SECURITY_SWITCH_REGISTER_SCOM,
    //                        l_security_switch_data),
    //         "Error from putScom (Security Switch Register");

fapi_try_exit:
    FAPI_INF("End");
    return fapi2::current_err;
}
<commit_msg>Port p10_rng_init_phase2 (2/2)<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/nest/p10_rng_init_phase2.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 p10_rng_init_phase2.C
/// @brief Perform NX RNG Phase 2 initialization (FAPI2)
///

//
// *HWP HWP Owner: Nicholas Landi <nlandi@ibm.com>
// *HWP FW Owner: Ilya Smirnov <ismirno@us.ibm.com>
// *HWP Consumed by: Cronus, HB
//

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p10_rng_init_phase2.H>
#include <p10_scom_proc.H>
#include <p10_scom_perv_8.H>
#include <p10_fbc_utils.H>

//------------------------------------------------------------------------------
// Constant definitions
//------------------------------------------------------------------------------
const uint8_t ADDR_SHIFT = 12;

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

fapi2::ReturnCode
p10_rng_init_phase2(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    using namespace scomt;
    using namespace scomt::proc;

    FAPI_INF("Start");
    fapi2::buffer<uint64_t> l_rng_cfg_data;
    fapi2::buffer<uint64_t> l_rng_bar_data;
    fapi2::buffer<uint64_t> l_rng_failed_int_data;
    fapi2::buffer<uint64_t> l_security_switch_data;

    uint64_t l_rng_cfg_self_test_hard_fail_status = 0;
    uint8_t  l_nx_rng_bar_enable = 0;
    uint64_t l_nx_rng_bar_addr = 0;
    uint64_t l_nx_rng_bar_base_addr_offset = 0;
    uint8_t  l_nx_rng_failed_int_enable = 0;
    uint64_t l_nx_rng_failed_int_addr = 0;
    uint64_t l_base_addr_nm0 = 0;
    uint64_t l_base_addr_nm1 = 0;
    uint64_t l_base_addr_m = 0;
    uint64_t l_base_addr_mmio = 0;

    // 5. RNG is allowed to run for M cycles (M = enough time to complete init;
    // recommend 1 second of time).
    // NOTE: accomplished by delay in execution time between phase1/phase2 HWPs

    FAPI_TRY(GET_NX_PBI_RNG_CFG(i_target, l_rng_cfg_data));

    // 6. Host boot checks RNG fail bits again and if a fail is detected
    // then RNG is declared broken

    FAPI_DBG("Checking RNG fail status...");
    // exit if failure is reported in self test hard fail status field
    GET_NX_PBI_RNG_CFG_FAIL_REG(l_rng_cfg_data, l_rng_cfg_self_test_hard_fail_status);
    FAPI_ASSERT(!l_rng_cfg_self_test_hard_fail_status,
                fapi2::P10_RNG_INIT_SELF_TEST_FAILED_ERR().
                set_TARGET(i_target).
                set_SELF_TEST_HARD_FAIL_STATUS(l_rng_cfg_self_test_hard_fail_status),
                "Self test hard fail status indicates failure");

    // 7. Host boot maps RNG BARs (see Section 5.31 RNG BAR on page 185).
    // • NX RNG BAR (not mapped/enabled if RNG is broken)
    // • NCU RNG BAR (always mapped to good RNG)
    // • NX RNG Fail Interrupt Addres

    // self test indicates no hard fail
    // if instructed to map the BAR:
    // - enable NX RNG MMIO BAR and get the bar address attributes
    // - optionally map NX RNG failed interrupt address
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_ENABLE,
                           i_target,
                           l_nx_rng_bar_enable),
             "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_ENABLE)");

    FAPI_TRY(p10_fbc_utils_get_chip_base_address(i_target,
             EFF_TOPOLOGY_ID,
             l_base_addr_nm0,
             l_base_addr_nm1,
             l_base_addr_m,
             l_base_addr_mmio),
             "Error from p10_fbc_utils_get_chip_base_address");

    // get RNG BAR addr
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_BAR_BASE_ADDR_OFFSET,
                           i_target.getParent<fapi2::TARGET_TYPE_SYSTEM>(),
                           l_nx_rng_bar_base_addr_offset),
             "Error from FAPI_ATTR_GET (ATTR_PROC_NX_BAR_BASE_ADDR_OFFSET)");

    // caculate the NX RNG BAR ADDR based on the bar addr offset
    l_nx_rng_bar_addr = l_base_addr_mmio + l_nx_rng_bar_base_addr_offset;

    FAPI_DBG("FBC_Util returned mmio base address of: 0x%016llx", l_base_addr_mmio);
    FAPI_DBG("Base nx offset:                         0x%016llx", l_nx_rng_bar_base_addr_offset);
    FAPI_DBG("Calculated offset:                      0x%016llx", l_nx_rng_bar_addr);

    if (l_nx_rng_bar_enable == fapi2::ENUM_ATTR_PROC_NX_RNG_BAR_ENABLE_ENABLE)
    {
        FAPI_TRY(PREP_NX_PBI_CQ_WRAP_NXCQ_SCOM_MMIO_BAR(i_target));
        // map NX RNG MMIO BAR

        SET_NX_PBI_CQ_WRAP_NXCQ_SCOM_MMIO_BAR_MMIO_BAR((l_nx_rng_bar_addr >> ADDR_SHIFT), l_rng_bar_data);
        SET_NX_PBI_CQ_WRAP_NXCQ_SCOM_MMIO_BAR_MMIO_BAR_ENABLE(l_rng_bar_data);

        FAPI_TRY(PUT_NX_PBI_CQ_WRAP_NXCQ_SCOM_MMIO_BAR(i_target, l_rng_bar_data));

        // map NX RNG failed interrupt address
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ENABLE,
                               i_target,
                               l_nx_rng_failed_int_enable),
                 "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ENABLE)");
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_NX_RNG_FAILED_INT_ADDR,
                               i_target,
                               l_nx_rng_failed_int_addr),
                 "Error from FAPI_ATTR_GET (ATTR_PROC_NX_RNG_FAILED_INT_ADDR)");

        if (l_nx_rng_failed_int_enable ==
            fapi2::ENUM_ATTR_PROC_NX_RNG_FAILED_INT_ENABLE_ENABLE)
        {
            FAPI_TRY(PREP_NX_PBI_UMAC_RNG_FAILED_INT(i_target));

            SET_NX_PBI_UMAC_RNG_FAILED_INT_ENABLE(l_rng_failed_int_data);
            SET_NX_PBI_UMAC_RNG_FAILED_INT_ADDRESS((l_nx_rng_failed_int_addr >> ADDR_SHIFT), l_rng_failed_int_data);

            FAPI_TRY(PUT_NX_PBI_UMAC_RNG_FAILED_INT(i_target, l_rng_failed_int_data));
        }
        else
        {
            FAPI_DBG("Skipping setup of NX RNG Failed Interrupt Address Register");
        }
    }
    else
    {
        FAPI_DBG("Skipping NX RNG BAR programming!");
    }

    // set NX RNG enable
    SET_NX_PBI_RNG_CFG_RNG_ENABLE(l_rng_cfg_data);
    FAPI_TRY(PUT_NX_PBI_RNG_CFG(i_target, l_rng_cfg_data));

    // 8. Host boot sets the NX “sticky bit” that asserts
    // tc_nx_block_rng_scom_wr. If tc_nx_block_rng_scom_wr = 1 writes to RNG
    // SCOM register addresses 32 - 38 and 40 are blocked. An attempted
    // write sets Power-Bus Interface FIR Data Register[Write to RNG SCOM
    // reg detected when writes disabled].

    // set NX sticky bit to block future RNG SCOM writes
    // (tc_nx_block_rng_scom_wr)
    FAPI_TRY(scomt::perv::GET_OTPC_M_SECURITY_SWITCH_REGISTER(i_target, l_security_switch_data));

    scomt::perv::SET_OTPC_M_SECURITY_SWITCH_REGISTER_NX_RAND_NUM_GEN_LOCK(l_security_switch_data);

    FAPI_TRY(scomt::perv::PUT_OTPC_M_SECURITY_SWITCH_REGISTER(i_target, l_security_switch_data));

fapi_try_exit:
    FAPI_INF("End");
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>//
// Created by padeler on 21/6/2017.
//

#include "OpenPoseWrapper.h"

#include <glog/logging.h>

#include <openpose/core/headers.hpp>
#include <openpose/core/scaleAndSizeExtractor.hpp>
#include <openpose/gui/headers.hpp>

#include <openpose/pose/headers.hpp>
#include <openpose/face/headers.hpp>
#include <openpose/hand/headers.hpp>

#include <openpose/utilities/headers.hpp>

#include <boost/throw_exception.hpp>

// Detector specific paramters are here:
//#include <openpose/hand/handParameters.hpp>
//#include <openpose/face/faceParameters.hpp>
//#include <openpose/pose/poseParameters.hpp>

struct OpenPoseWrapper::PrivateData
{
    PrivateData(const op::Point<int> &netInputSize, const op::Point<int> &netInputSizeFaceAndHands,
                const op::Point<int> &outputSize, const op::PoseModel &poseModel,
                const std::string &modelFolder, int numScales, float scaleGap, float blendAlpha,
                const std::vector<op::HeatMapType> &heatMapTypes, const op::ScaleMode &heatMapScale, int gpuId):
            poseExtractorCaffe{poseModel, modelFolder, gpuId, heatMapTypes, heatMapScale},
            poseRenderer{poseModel, nullptr, 0.05, true, blendAlpha},
            scaleAndSizeExtractor{netInputSize, outputSize, numScales, scaleGap},

            faceExtractor{netInputSizeFaceAndHands, netInputSizeFaceAndHands, modelFolder, gpuId, heatMapTypes, heatMapScale},
            faceRenderer{0.4},
            faceDetector(poseModel),

            handDetector(poseModel),
            handRenderer{0.2},
            handExtractor{netInputSizeFaceAndHands, netInputSizeFaceAndHands, modelFolder, gpuId, 1, 0.4, heatMapTypes, heatMapScale}

    {}

    op::CvMatToOpInput cvMatToOpInput;
    op::CvMatToOpOutput cvMatToOpOutput;
    op::PoseExtractorCaffe poseExtractorCaffe;

    op::PoseGpuRenderer poseRenderer;

    op::FaceExtractorCaffe faceExtractor;
    op::FaceDetector faceDetector;
    op::FaceGpuRenderer faceRenderer;

    op::HandExtractorCaffe handExtractor;
    op::HandDetector handDetector;
    op::HandGpuRenderer handRenderer;

    op::OpOutputToCvMat opOutputToCvMat;
    op::ScaleAndSizeExtractor scaleAndSizeExtractor;
};

OpenPoseWrapper::OpenPoseWrapper(const cv::Size &netPoseSize, const cv::Size &netFaceHandsSize, const cv::Size &outSize,
                                 const std::string &model, const std::string &modelFolder, const int logLevel,
                                 bool downloadHeatmaps, OpenPoseWrapper::ScaleMode scaleMode, bool withFace, bool withHands, int gpuId):withFace(withFace), withHands(withHands) {
//    google::InitGoogleLogging("OpenPose Wrapper");

    // Step 1 - Set logging level
    // - 0 will output all the logging messages
    // - 255 will output nothing

    op::check(0 <= logLevel && logLevel <= 255, "Wrong logging_level value.", __LINE__, __FUNCTION__, __FILE__);
    op::ConfigureLog::setPriorityThreshold((op::Priority)logLevel);

    // Step 2 - Init params
    op::Point<int> outputSize(outSize.width,outSize.height);
    op::Point<int> netInputSize(netPoseSize.width,netPoseSize.height);
    op::Point<int> netInputSizeFaceAndHands(netFaceHandsSize.width,netFaceHandsSize.height);

    op::PoseModel poseModel;

    op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__);
    if (model == "COCO")
        poseModel = op::PoseModel::COCO_18;
    else if (model == "MPI")
        poseModel = op::PoseModel::MPI_15;
    else if (model == "MPI_4_layers")
        poseModel = op::PoseModel::MPI_15_4;
    else
    {
        op::error("String does not correspond to any model (COCO, MPI, MPI_4_layers)", __LINE__, __FUNCTION__, __FILE__);
        poseModel = op::PoseModel::COCO_18;
    }

    int numScales = 1;
    float scaleGap = 0.3; // not used if numScales==1
    float blendAlpha = 0.6;

    //if you need to download bodypart heatmaps, Background or PAFs. They must be enabled here.
    std::vector<op::HeatMapType> hmt = {};
    if(downloadHeatmaps)
    {
        hmt = {op::HeatMapType::Parts, op::HeatMapType::Background, op::HeatMapType::PAFs};
    }

    // Step 3 - Initialize all required classes
    membersPtr = std::shared_ptr<PrivateData>(new PrivateData(netInputSize, netInputSizeFaceAndHands,
                                                              outputSize, poseModel, modelFolder,
                                                              numScales, scaleGap, blendAlpha,
                                                              hmt, (op::ScaleMode)scaleMode, gpuId));

    // Step 4 - Initialize resources on desired thread (in this case single thread, i.e. we init resources here)
    membersPtr->poseExtractorCaffe.initializationOnThread();
    membersPtr->poseRenderer.initializationOnThread();
    if(withFace) {
        membersPtr->faceExtractor.initializationOnThread();
        membersPtr->faceRenderer.initializationOnThread();
    }
    if(withHands) {
        membersPtr->handExtractor.initializationOnThread();
        membersPtr->handRenderer.initializationOnThread();
    }
}

void OpenPoseWrapper::detectPose(const cv::Mat &rgb) {
    // Step 2 - Format input image to OpenPose input and output formats

    const op::Point<int> imageSize{rgb.cols, rgb.rows};
    std::vector<double> scaleInputToNetInputs;
    std::vector<op::Point<int>> netInputSizes;
    double scaleInputToOutput;
    op::Point<int> outputResolution;
    std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution)
            = membersPtr->scaleAndSizeExtractor.extract(imageSize);
    std::vector<op::Array<float>> netInputArray = membersPtr->cvMatToOpInput.createArray(rgb, scaleInputToNetInputs, netInputSizes);

    // Step 3 - Estimate poseKeypoints
    membersPtr->poseExtractorCaffe.forwardPass(netInputArray, imageSize, scaleInputToNetInputs);
}

void OpenPoseWrapper::detectFace(const cv::Mat &rgb) {
    if(!withFace)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Face network was not initialized."));
    }
    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    const auto faceRectsOP = membersPtr->faceDetector.detectFaces(poseKeypoints, 1.0f);

    this->faceRects = cv::Mat(faceRectsOP.size(), 4, CV_32SC1, cv::Scalar(0));
    cv::Mat fr = this->faceRects.reshape(4,faceRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(faceRectsOP.begin(), faceRectsOP.end(), fr.begin<cv::Vec4i>(), [](const op::Rectangle<float> &r) -> cv::Vec4i { return cv::Vec4i(r.x, r.y, r.width, r.height);});

    membersPtr->faceExtractor.forwardPass(faceRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectFace(const cv::Mat &rgb, const cv::Mat &faceRects)
{
    if(!withFace)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Face network was not initialized."));
    }
    if(faceRects.cols!=4 or faceRects.type()!=CV_32SC1)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Invalid face rectangles format. Expected Nx4 mat with type CV_32SC1"));
    }

    this->faceRects = faceRects; // keep a copy
    std::vector<op::Rectangle<float> > faceRectsOP(faceRects.rows);
    cv::Mat fr = faceRects.reshape(4,faceRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(fr.begin<cv::Vec4i>(), fr.end<cv::Vec4i>(), faceRectsOP.begin(),
                   [](const cv::Vec4i &r) -> op::Rectangle<float> { return op::Rectangle<float>(r[0], r[1], r[2], r[3]);});

    membersPtr->faceExtractor.forwardPass(faceRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectHands(const cv::Mat &rgb) {
    if(!withHands)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Hand network was not initialized."));
    }

    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    const auto handRectsOP = membersPtr->handDetector.detectHands(poseKeypoints, 1.0f);

    this->handRects= cv::Mat(handRectsOP.size(), 8, CV_32SC1, cv::Scalar(0));
    cv::Mat hr = this->handRects.reshape(8,handRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(handRectsOP.begin(), handRectsOP.end(), hr.begin<cv::Vec8i>(),
                   [](const std::array<op::Rectangle<float>, 2> &r) -> cv::Vec8i
                   { return cv::Vec8i(r[0].x, r[0].y, r[0].width, r[0].height, r[1].x, r[1].y, r[1].width, r[1].height); });

    membersPtr->handExtractor.forwardPass(handRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectHands(const cv::Mat &rgb, const cv::Mat &handRects)
{
    if(!withHands)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Hand network was not initialized."));
    }
    if(handRects.cols!=8 or handRects.type()!=CV_32SC1)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Invalid hand rectangles format. Expected Nx8 mat with type CV_32SC1"));
    }

    this->handRects = handRects;
    std::vector<std::array<op::Rectangle<float>, 2> > handRectsOP(handRects.rows);
    cv::Mat hr = handRects.reshape(8,handRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(hr.begin<cv::Vec8i>(), hr.end<cv::Vec8i>(), handRectsOP.begin(),
                   [](const cv::Vec8i &r) -> std::array<op::Rectangle<float>, 2>
                   { return std::array<op::Rectangle<float>, 2>{op::Rectangle<float>(r[0], r[1], r[2], r[3]), op::Rectangle<float>(r[4], r[5], r[6], r[7])};});

    membersPtr->handExtractor.forwardPass(handRectsOP, rgb, 1.0f);
}

cv::Mat OpenPoseWrapper::render(const cv::Mat &rgb)
{
    op::Array<float> outputArray;

    const op::Point<int> imageSize{rgb.cols, rgb.rows};
    std::vector<double> scaleInputToNetInputs;
    std::vector<op::Point<int>> netInputSizes;
    double scaleInputToOutput;
    op::Point<int> outputResolution;
    std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution)
            = membersPtr->scaleAndSizeExtractor.extract(imageSize);

    outputArray = membersPtr->cvMatToOpOutput.createArray(rgb, scaleInputToOutput, outputResolution);

    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    membersPtr->poseRenderer.renderPose(outputArray, poseKeypoints, scaleInputToOutput);

    if(withFace){
        const auto faceKeypoints = membersPtr->faceExtractor.getFaceKeypoints();
        membersPtr->faceRenderer.renderFace(outputArray, faceKeypoints);
    }
    if(withHands) {
        const auto handKeypoints = membersPtr->handExtractor.getHandKeypoints();
        membersPtr->handRenderer.renderHand(outputArray, handKeypoints);
    }

    auto outputImage = membersPtr->opOutputToCvMat.formatToCvMat(outputArray);
    return outputImage;
}

OpenPoseWrapper::KeypointGroups OpenPoseWrapper::getKeypoints(KeypointType kpt) {

    op::Array<float> faces,persons;
    std::array<op::Array<float>, 2> hands;

    KeypointGroups res;
    switch(kpt){
        case FACE:
            faces = membersPtr->faceExtractor.getFaceKeypoints();
            res.push_back(faces.getConstCvMat()); // all faces in a cv::Mat at index 0
            break;
        case HAND:
            hands = membersPtr->handExtractor.getHandKeypoints();
            res.push_back(hands[0].getConstCvMat()); // left hands cv::Mat
            res.push_back(hands[1].getConstCvMat()); // right hands cv::Mat
            break;
        default: // POSE
            persons = membersPtr->poseExtractorCaffe.getPoseKeypoints();
            res.push_back(persons.getConstCvMat()); // all persons in a cv::Mat at index 0
            break;
    }

    return res;
}

cv::Mat OpenPoseWrapper::getHeatmaps() {
    op::Array<float> maps = membersPtr->poseExtractorCaffe.getHeatMapsCopy();
    return maps.getConstCvMat().clone();
}

std::vector<cv::Mat> OpenPoseWrapper::getHandHeatmaps() {

    std::array<op::Array<float>, 2> maps = membersPtr->handExtractor.getHeatMaps();

    std::vector<cv::Mat> res;
    res.push_back(maps.at(0).getConstCvMat().clone());
    res.push_back(maps.at(1).getConstCvMat().clone());
    return res;
}

cv::Mat OpenPoseWrapper::getFaceHeatmaps() {
    op::Array<float> maps = membersPtr->faceExtractor.getHeatMaps();
    return maps.getConstCvMat().clone();
}
<commit_msg>Fix issue #43<commit_after>//
// Created by padeler on 21/6/2017.
//

#include "OpenPoseWrapper.h"

#include <glog/logging.h>

#include <openpose/core/headers.hpp>
#include <openpose/core/scaleAndSizeExtractor.hpp>
#include <openpose/gui/headers.hpp>

#include <openpose/pose/headers.hpp>
#include <openpose/face/headers.hpp>
#include <openpose/hand/headers.hpp>

#include <openpose/utilities/headers.hpp>

#include <boost/throw_exception.hpp>

// Detector specific paramters are here:
//#include <openpose/hand/handParameters.hpp>
//#include <openpose/face/faceParameters.hpp>
//#include <openpose/pose/poseParameters.hpp>

struct OpenPoseWrapper::PrivateData
{
    PrivateData(const op::Point<int> &netInputSize, const op::Point<int> &netInputSizeFaceAndHands,
                const op::Point<int> &outputSize, const op::PoseModel &poseModel,
                const std::string &modelFolder, int numScales, float scaleGap, float blendAlpha,
                const std::vector<op::HeatMapType> &heatMapTypes, const op::ScaleMode &heatMapScale, int gpuId):
            poseExtractorCaffe{poseModel, modelFolder, gpuId, heatMapTypes, heatMapScale},
            poseRenderer{poseModel, nullptr, 0.05, true, blendAlpha},
            scaleAndSizeExtractor{netInputSize, outputSize, numScales, scaleGap},

            faceExtractor{netInputSizeFaceAndHands, netInputSizeFaceAndHands, modelFolder, gpuId, heatMapTypes, heatMapScale},
            faceRenderer{0.4},
            faceDetector(poseModel),

            handDetector(poseModel),
            handRenderer{0.2},
            handExtractor{netInputSizeFaceAndHands, netInputSizeFaceAndHands, modelFolder, gpuId, 1, 0.4, heatMapTypes, heatMapScale}

    {}

    op::CvMatToOpInput cvMatToOpInput;
    op::CvMatToOpOutput cvMatToOpOutput;
    op::PoseExtractorCaffe poseExtractorCaffe;

    op::PoseGpuRenderer poseRenderer;

    op::FaceExtractorCaffe faceExtractor;
    op::FaceDetector faceDetector;
    op::FaceGpuRenderer faceRenderer;

    op::HandExtractorCaffe handExtractor;
    op::HandDetector handDetector;
    op::HandGpuRenderer handRenderer;

    op::OpOutputToCvMat opOutputToCvMat;
    op::ScaleAndSizeExtractor scaleAndSizeExtractor;
};

OpenPoseWrapper::OpenPoseWrapper(const cv::Size &netPoseSize, const cv::Size &netFaceHandsSize, const cv::Size &outSize,
                                 const std::string &model, const std::string &modelFolder, const int logLevel,
                                 bool downloadHeatmaps, OpenPoseWrapper::ScaleMode scaleMode, bool withFace, bool withHands, int gpuId):withFace(withFace), withHands(withHands) {
//    google::InitGoogleLogging("OpenPose Wrapper");

    // Step 1 - Set logging level
    // - 0 will output all the logging messages
    // - 255 will output nothing

    op::check(0 <= logLevel && logLevel <= 255, "Wrong logging_level value.", __LINE__, __FUNCTION__, __FILE__);
    op::ConfigureLog::setPriorityThreshold((op::Priority)logLevel);

    // Step 2 - Init params
    op::Point<int> outputSize(outSize.width,outSize.height);
    op::Point<int> netInputSize(netPoseSize.width,netPoseSize.height);
    op::Point<int> netInputSizeFaceAndHands(netFaceHandsSize.width,netFaceHandsSize.height);

    op::PoseModel poseModel;

    op::log("", op::Priority::Low, __LINE__, __FUNCTION__, __FILE__);
    if (model == "COCO")
        poseModel = op::PoseModel::COCO_18;
    else if (model == "MPI")
        poseModel = op::PoseModel::MPI_15;
    else if (model == "MPI_4_layers")
        poseModel = op::PoseModel::MPI_15_4;
    else
    {
        op::error("String does not correspond to any model (COCO, MPI, MPI_4_layers)", __LINE__, __FUNCTION__, __FILE__);
        poseModel = op::PoseModel::COCO_18;
    }

    int numScales = 1;
    float scaleGap = 0.3; // not used if numScales==1
    float blendAlpha = 0.6;

    //if you need to download bodypart heatmaps, Background or PAFs. They must be enabled here.
    std::vector<op::HeatMapType> hmt = {};
    if(downloadHeatmaps)
    {
        hmt = {op::HeatMapType::Parts, op::HeatMapType::Background, op::HeatMapType::PAFs};
    }

    // Step 3 - Initialize all required classes
    membersPtr = std::shared_ptr<PrivateData>(new PrivateData(netInputSize, netInputSizeFaceAndHands,
                                                              outputSize, poseModel, modelFolder,
                                                              numScales, scaleGap, blendAlpha,
                                                              hmt, (op::ScaleMode)scaleMode, gpuId));

    // Step 4 - Initialize resources on desired thread (in this case single thread, i.e. we init resources here)
    membersPtr->poseExtractorCaffe.initializationOnThread();
    membersPtr->poseRenderer.initializationOnThread();
    if(withFace) {
        membersPtr->faceExtractor.initializationOnThread();
        membersPtr->faceRenderer.initializationOnThread();
    }
    if(withHands) {
        membersPtr->handExtractor.initializationOnThread();
        membersPtr->handRenderer.initializationOnThread();
    }
}

void OpenPoseWrapper::detectPose(const cv::Mat &rgb) {
    // Step 2 - Format input image to OpenPose input and output formats

    const op::Point<int> imageSize{rgb.cols, rgb.rows};
    std::vector<double> scaleInputToNetInputs;
    std::vector<op::Point<int>> netInputSizes;
    double scaleInputToOutput;
    op::Point<int> outputResolution;
    std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution)
            = membersPtr->scaleAndSizeExtractor.extract(imageSize);
    std::vector<op::Array<float>> netInputArray = membersPtr->cvMatToOpInput.createArray(rgb, scaleInputToNetInputs, netInputSizes);

    // Step 3 - Estimate poseKeypoints
    membersPtr->poseExtractorCaffe.forwardPass(netInputArray, imageSize, scaleInputToNetInputs);
}

void OpenPoseWrapper::detectFace(const cv::Mat &rgb) {
    if(!withFace)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Face network was not initialized."));
    }
    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    const auto faceRectsOP = membersPtr->faceDetector.detectFaces(poseKeypoints);

    this->faceRects = cv::Mat(faceRectsOP.size(), 4, CV_32SC1, cv::Scalar(0));
    cv::Mat fr = this->faceRects.reshape(4,faceRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(faceRectsOP.begin(), faceRectsOP.end(), fr.begin<cv::Vec4i>(), [](const op::Rectangle<float> &r) -> cv::Vec4i { return cv::Vec4i(r.x, r.y, r.width, r.height);});

    membersPtr->faceExtractor.forwardPass(faceRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectFace(const cv::Mat &rgb, const cv::Mat &faceRects)
{
    if(!withFace)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Face network was not initialized."));
    }
    if(faceRects.cols!=4 or faceRects.type()!=CV_32SC1)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Invalid face rectangles format. Expected Nx4 mat with type CV_32SC1"));
    }

    this->faceRects = faceRects; // keep a copy
    std::vector<op::Rectangle<float> > faceRectsOP(faceRects.rows);
    cv::Mat fr = faceRects.reshape(4,faceRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(fr.begin<cv::Vec4i>(), fr.end<cv::Vec4i>(), faceRectsOP.begin(),
                   [](const cv::Vec4i &r) -> op::Rectangle<float> { return op::Rectangle<float>(r[0], r[1], r[2], r[3]);});

    membersPtr->faceExtractor.forwardPass(faceRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectHands(const cv::Mat &rgb) {
    if(!withHands)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Hand network was not initialized."));
    }

    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    const auto handRectsOP = membersPtr->handDetector.detectHands(poseKeypoints);

    this->handRects= cv::Mat(handRectsOP.size(), 8, CV_32SC1, cv::Scalar(0));
    cv::Mat hr = this->handRects.reshape(8,handRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(handRectsOP.begin(), handRectsOP.end(), hr.begin<cv::Vec8i>(),
                   [](const std::array<op::Rectangle<float>, 2> &r) -> cv::Vec8i
                   { return cv::Vec8i(r[0].x, r[0].y, r[0].width, r[0].height, r[1].x, r[1].y, r[1].width, r[1].height); });

    membersPtr->handExtractor.forwardPass(handRectsOP, rgb, 1.0f);
}

void OpenPoseWrapper::detectHands(const cv::Mat &rgb, const cv::Mat &handRects)
{
    if(!withHands)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Hand network was not initialized."));
    }
    if(handRects.cols!=8 or handRects.type()!=CV_32SC1)
    {
        BOOST_THROW_EXCEPTION(std::runtime_error("Invalid hand rectangles format. Expected Nx8 mat with type CV_32SC1"));
    }

    this->handRects = handRects;
    std::vector<std::array<op::Rectangle<float>, 2> > handRectsOP(handRects.rows);
    cv::Mat hr = handRects.reshape(8,handRects.rows); // stupid cv::Mat iterator cannot iterate over rows.
    std::transform(hr.begin<cv::Vec8i>(), hr.end<cv::Vec8i>(), handRectsOP.begin(),
                   [](const cv::Vec8i &r) -> std::array<op::Rectangle<float>, 2>
                   { return std::array<op::Rectangle<float>, 2>{op::Rectangle<float>(r[0], r[1], r[2], r[3]), op::Rectangle<float>(r[4], r[5], r[6], r[7])};});

    membersPtr->handExtractor.forwardPass(handRectsOP, rgb, 1.0f);
}

cv::Mat OpenPoseWrapper::render(const cv::Mat &rgb)
{
    op::Array<float> outputArray;

    const op::Point<int> imageSize{rgb.cols, rgb.rows};
    std::vector<double> scaleInputToNetInputs;
    std::vector<op::Point<int>> netInputSizes;
    double scaleInputToOutput;
    op::Point<int> outputResolution;
    std::tie(scaleInputToNetInputs, netInputSizes, scaleInputToOutput, outputResolution)
            = membersPtr->scaleAndSizeExtractor.extract(imageSize);

    outputArray = membersPtr->cvMatToOpOutput.createArray(rgb, scaleInputToOutput, outputResolution);

    const auto poseKeypoints = membersPtr->poseExtractorCaffe.getPoseKeypoints();
    membersPtr->poseRenderer.renderPose(outputArray, poseKeypoints, scaleInputToOutput);

    if(withFace){
        const auto faceKeypoints = membersPtr->faceExtractor.getFaceKeypoints();
        membersPtr->faceRenderer.renderFace(outputArray, faceKeypoints);
    }
    if(withHands) {
        const auto handKeypoints = membersPtr->handExtractor.getHandKeypoints();
        membersPtr->handRenderer.renderHand(outputArray, handKeypoints);
    }

    auto outputImage = membersPtr->opOutputToCvMat.formatToCvMat(outputArray);
    return outputImage;
}

OpenPoseWrapper::KeypointGroups OpenPoseWrapper::getKeypoints(KeypointType kpt) {

    op::Array<float> faces,persons;
    std::array<op::Array<float>, 2> hands;

    KeypointGroups res;
    switch(kpt){
        case FACE:
            faces = membersPtr->faceExtractor.getFaceKeypoints();
            res.push_back(faces.getConstCvMat()); // all faces in a cv::Mat at index 0
            break;
        case HAND:
            hands = membersPtr->handExtractor.getHandKeypoints();
            res.push_back(hands[0].getConstCvMat()); // left hands cv::Mat
            res.push_back(hands[1].getConstCvMat()); // right hands cv::Mat
            break;
        default: // POSE
            persons = membersPtr->poseExtractorCaffe.getPoseKeypoints();
            res.push_back(persons.getConstCvMat()); // all persons in a cv::Mat at index 0
            break;
    }

    return res;
}

cv::Mat OpenPoseWrapper::getHeatmaps() {
    op::Array<float> maps = membersPtr->poseExtractorCaffe.getHeatMapsCopy();
    return maps.getConstCvMat().clone();
}

std::vector<cv::Mat> OpenPoseWrapper::getHandHeatmaps() {

    std::array<op::Array<float>, 2> maps = membersPtr->handExtractor.getHeatMaps();

    std::vector<cv::Mat> res;
    res.push_back(maps.at(0).getConstCvMat().clone());
    res.push_back(maps.at(1).getConstCvMat().clone());
    return res;
}

cv::Mat OpenPoseWrapper::getFaceHeatmaps() {
    op::Array<float> maps = membersPtr->faceExtractor.getHeatMaps();
    return maps.getConstCvMat().clone();
}
<|endoftext|>


<commit_before>#include "tinfra/fs.h"
#include "tinfra/tstring.h"

using tinfra::tstring;
using std::vector;

typedef vector<std::string> plist;
typedef vector<tstring> vlist;

struct  task {
     vector<vlist> statements;
};

void parse(std::string const& input, task& task)
{
    const char* first = &input[0];
    const char* c = first;
    const char* last = &input[input.size()-1];
    enum {
        NORMAL,
        WORD,
        IN_QUOTES,
    } state;
    while( c != last ) {
        switch( state ) {
        case NORMAL:
            if( isspace(*c) ) {
                c++;
                continue;
            } if( *c == '"' ) {
                state = IN_QUOTES;
                c++;
                first_char =
            }

        case WORD:
        case IN_QUOTES:
        }
    }
}
int main()
{
}<commit_msg>super list generator idea added<commit_after>
// lsfoo - file list generator
//
//   generates many file lists from several source trees
//   each of list gather different set of files, kinda find | awk 'COMPLICATED SCRIPT' on steroids
//
//  rules example:
//    sources-foo include-glob     src/*.{cpp|cc|C|c++|c}
//                                 # equivalent to src/*.cpp src/*.cc src/*.C ...
//    sources-foo include-regexp   src/.*.(cpp|cc|C|c++|c)$
//
//    sources-foo file             sources-foo.xml
//    sources-foo format           makefile-dep sources-foo

//    sources-foo output-format    text
//    sources-foo output-format    xml [root] [item]
//    sources-foo output-format    json

//    # globs have to be at bottom, because they actively affect
//    # already declared lists
//
//    *   exclude-glob .git
//                  -- *~

#include "tinfra/fs.h"
#include "tinfra/tstring.h"

using tinfra::tstring;
using std::vector;

void consume_whitespace(tstring& line)
{
    tstring::iterator c = line.begin();
    while( c != line.end() ) {
        if( !isspace(*c) ) {
            break;
        }
        c++;
    }
    if( c != line.begin() ) {
        line = line.substr( c - line.begin() );
    }
}

void strip_endline( tstring& line )
{
    if( line.size() == 0 )
        return;

    const auto size = line.size();
    if( line[size - 1] == '\n' ) {
        if( size > 1 && line[size - 2] == '\r' ) {
            line = line.substr(0, size - 2);
        } else {
            line = line.substr(0, size - 1);
        }
    }
}

tstring rest(tstring& line)
{
    consume_whitespace( line );
    tstring result = line;
    strip_endline( result );
    line = "";
}

tstring next_word(tstring& line)
{
    consume_whitespace( line );
    tstring::iterator c = line.begin();
    while( c != line.end() ) {
        if( !isspace(*c) ) {
            c++;
            continue;
        } else {
            break;
        }
    }
    tstring result = line.substr( 0, c - line.begin() );
    line = line.substr( c - line.begin() );
    return result;
}

struct list_definition {

};

std::map<tstring, list_definition> lists;

void parse(tstring line)
{
    tstring list_specifier = next_word(line);
    if( list_specifier.empty() ) {
        return;
    }
    if( list_specifier == '*' ) {
    }
}
int main()
{
}<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
int T;
int t[110];
int v[110];
int w[50000];

int main () {
  cin >> N;
  T = 0;
  for (auto i = 0; i < N; ++i) {
    cin >> t[i];
    t[i] *= 2;
    T += t[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> v[i];
    v[i] *= 2;
  }
  for (auto i = 0; i <= T; ++i) {
    w[i] = min(i, T - i);
  }
  int sum = 0;
  for (auto i = 0; i < N; ++i) {
    cerr << "i = " << i << endl;
    int all = sum + t[i];
    for (auto j = 0; sum-j >= 0; --j) {
      w[sum-j] = min(w[sum-j], v[i]+j);
    }
    for (auto j = sum; j <= all; ++j) {
      w[j] = min(w[j], v[i]);
    }
    for (auto j = 0; all+j <= T; ++j) {
      w[all+j] = min(w[all+j], v[i]+j);
    }
    sum += t[i];
  }
  double ans = 0;
  for (auto i = 0; i < T; ++i) {
    ans += ((double)w[i] + (double)w[i+1])/2;
  }
  cout << fixed << setprecision(10) << ans/4 << endl;
}
<commit_msg>tried D.cpp to 'D'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

int N;
int T;
int t[110];
int v[110];
int w[50000];

int main () {
  cin >> N;
  T = 0;
  for (auto i = 0; i < N; ++i) {
    cin >> t[i];
    t[i] *= 2;
    T += t[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> v[i];
    v[i] *= 2;
  }
  for (auto i = 0; i <= T; ++i) {
    w[i] = min(i, T - i);
  }
  int sum = 0;
  for (auto i = 0; i < N; ++i) {
    int all = sum + t[i];
    for (auto j = 0; sum-j >= 0; ++j) {
      w[sum-j] = min(w[sum-j], v[i]+j);
    }
    for (auto j = sum; j <= all; ++j) {
      w[j] = min(w[j], v[i]);
    }
    for (auto j = 0; all+j <= T; ++j) {
      w[all+j] = min(w[all+j], v[i]+j);
    }
    sum += t[i];
  }
  double ans = 0;
  for (auto i = 0; i < T; ++i) {
    ans += ((double)w[i] + (double)w[i+1])/2;
  }
  cout << fixed << setprecision(10) << ans/4 << endl;
}
<|endoftext|>


<commit_before>/*
 * This program is just for personal experiments here on AVR features and C++ stuff
 * to check compilation and link of FastArduino port and pin API.
 * It does not do anything interesting as far as hardware is concerned.
 */

//TODO try it with a buzzer (direct wire or amplified?)
//TODO write a SquareWave class or namespace with utility methods
//TODO create simple melody
//TODO store melody to EEPROM and read it from there

// Example of square wave generation, using CTC mode and COM toggle
#include <fastarduino/analog_input.h>
#include <fastarduino/pwm.h>
#include <fastarduino/time.h>
#include <fastarduino/timer.h>
#include <fastarduino/utilities.h>

// Board-dependent settings
static constexpr const board::Timer NTIMER = board::Timer::TIMER1;
static constexpr const board::DigitalPin OUTPUT = board::PWMPin::D9_PB1_OC1A;
static constexpr const board::AnalogPin FREQ_INPUT = board::AnalogPin::A0;

using FREQ = analog::AnalogInput<FREQ_INPUT, uint8_t>;
using CALC = timer::Calculator<NTIMER>;
using TIMER = timer::Timer<NTIMER>;
using PWMPIN = analog::PWMOutput<OUTPUT>;

// Frequency range
static constexpr const uint32_t MIN_FREQ = 40UL;
static constexpr const uint32_t DEFAULT_FREQ = 440UL;
static constexpr const uint32_t MAX_FREQ = 20000UL;

static void init_frequency(TIMER& timer, PWMPIN& output, uint32_t frequency)
{
	timer.suspend();
	const uint32_t period = 1000000UL / 2 / frequency;
	TIMER::PRESCALER prescaler = CALC::CTC_prescaler(period);
	TIMER::TYPE counter = CALC::CTC_counter(prescaler, period);
	timer.set_prescaler(prescaler);
	output.set_duty(counter);
	timer.resume();
}

int main() __attribute__((OS_main));
int main()
{
	sei();

	FREQ input;
	TIMER timer{timer::TimerMode::CTC, TIMER::PRESCALER::NO_PRESCALING};
	PWMPIN output = PWMPIN{timer, timer::TimerOutputMode::TOGGLE};
	timer.begin();

	FREQ::SAMPLE_TYPE sample = 0xFF;
	while (true)
	{
		// Read analog pin
		FREQ::SAMPLE_TYPE new_sample = input.sample();
		if (new_sample != sample)
		{
			sample = new_sample;
			// Convert to frequency
			uint32_t frequency = utils::map(sample, uint8_t(0), uint8_t(255), MIN_FREQ, MAX_FREQ);
			// Set new frequency
			init_frequency(timer, output, frequency);
		}
		// Generate square wave for 100 milliseconds
		time::delay_ms(1000);
	}
}
<commit_msg>Tone generation example: progress.<commit_after>/*
 * This program is just for personal experiments here on AVR features and C++ stuff
 * to check compilation and link of FastArduino port and pin API.
 * It does not do anything interesting as far as hardware is concerned.
 */

//TODO try it with a buzzer (direct wire or amplified?)
//TODO write a SquareWave class or namespace with utility methods
//TODO create simple melody
//TODO store melody to EEPROM and read it from there

// Example of square wave generation, using CTC mode and COM toggle
#include <fastarduino/analog_input.h>
#include <fastarduino/pwm.h>
#include <fastarduino/time.h>
#include <fastarduino/timer.h>
#include <fastarduino/utilities.h>

// Board-dependent settings
static constexpr const board::Timer NTIMER = board::Timer::TIMER1;
static constexpr const board::DigitalPin OUTPUT = board::PWMPin::D9_PB1_OC1A;
static constexpr const board::AnalogPin FREQ_INPUT = board::AnalogPin::A0;

using FREQ = analog::AnalogInput<FREQ_INPUT, uint8_t>;
using CALC = timer::Calculator<NTIMER>;
using TIMER = timer::Timer<NTIMER>;
using PWMPIN = analog::PWMOutput<OUTPUT>;

// Frequency range
static constexpr const uint32_t MIN_FREQ = 40UL;
static constexpr const uint32_t DEFAULT_FREQ = 440UL;
static constexpr const uint32_t MAX_FREQ = 20000UL;

static void init_frequency(TIMER& timer, PWMPIN& output, uint32_t frequency)
{
	timer.end();
	const uint32_t period = 1000000UL / 2 / frequency;
	TIMER::PRESCALER prescaler = CALC::CTC_prescaler(period);
	TIMER::TYPE counter = CALC::CTC_counter(prescaler, period);
	timer.set_prescaler(prescaler);
	timer.begin();
	output.set_duty(counter);
}

int main() __attribute__((OS_main));
int main()
{
	sei();

	FREQ input;
	TIMER timer{timer::TimerMode::CTC, TIMER::PRESCALER::NO_PRESCALING};
	PWMPIN output = PWMPIN{timer, timer::TimerOutputMode::TOGGLE};

	FREQ::SAMPLE_TYPE sample = 0xFF;
	while (true)
	{
		// Read analog pin
		FREQ::SAMPLE_TYPE new_sample = input.sample();
		if (new_sample != sample)
		{
			sample = new_sample;
			// Convert to frequency
			uint32_t frequency = utils::map(sample, uint8_t(0), uint8_t(255), MIN_FREQ, MAX_FREQ);
			// Set new frequency
			init_frequency(timer, output, frequency);
		}
		// Generate square wave for 100 milliseconds
		time::delay_ms(1000);
	}
}
<|endoftext|>