Search:
Menu VisualVoice / Step1

Visual Voice Home


About Artistic Vision People Teams Contact us


Activities



Publications Media Images/Movies


Opportunities


Related Links


Local Only


Website problems?

edit SideBar

Running Artisynth's KuraFace as a Server Socket

Ordinarily, when Artisynth is launched, it opens to the main window, and the user must then load one of the available models in order to run it. For the sake of the DIVA project, only the KuraFace model will be used, and for the sake of efficiency, it would be ideal for the KuraFace to appear upon initialization, ready to receive values. For this purpose, an additional class was created in the Artisynth project, artisynth.core.driver.StartAS.

The StartAS class has the following behaviour:

i) Opens the Artisynth main window
ii) Loads the KuraFace model to the main window
iii) Opens a server-side socket, and
iv) Loops indefinitely,
.....a) awaiting a client connection
.....b) grabbing data from the client socket
.....c) using this data to set face parameters, and
.....d) refreshing the face model to apply parameters

The file StartAS.java is shown in its entirety below -- comments are added at important points, and a summary follows:

   package artisynth.core.driver;

   import java.awt.event.KeyListener;
   import artisynth.core.driver.GenericKeyHandler;
   import artisynth.core.driver.Main;
   import artisynth.core.util.JVMInfo;
   import java.net.*;
   import java.io.*;

   /**
    * StartAS is a helper class created in the Artisynth project for the sake of the DIVA project.  It performs
    * the following actions:
    * 
    * i) Opens the Artisynth Main Window
    * ii) Loads the KuraFace model to the Main Window
    * iii) Waits as server for a socket connection on port 4444
    * iv) Upon receiving a connection, runs in a loop to receive values through the socket,
    * and sends these values to stretch the Kura Face.
    * 
    * For more information on the KuraFace model, please see the Artisynth Guide in the Docs folder of the DIVA project,
    * or on DIVA's pmwiki pages, in the Local Only section.
    * 
    * @author Eric Foxall
    *
    */
   public class StartAS
   {

      /**
       * Performs actions described in class summary
       * @param args no arguments required
       */
      public static void main(String[] args)
      {

         // add librarypath
         try

          { JVMInfo.appendDefaultLibraryPath();

          }

         catch (Exception e)

          { System.out.println ("Error loading library path");

            e.printStackTrace();

          }

creates the main window, 600 x 600 pixels

        m = new Main("ArtiSynth", 600, 600);

        Main.getMainFrame().getMenuBarHandler().initToolbar ();
        Main.createWorkspace();

   //     for (KeyListener l : m.getViewer().getCanvas().getKeyListeners())
   //     { if (l instanceof GenericKeyHandler)
   //        { ((GenericKeyHandler)l).setToolBar (Main.getMainFrame().getMenuBarHandler().getViewerToolBar());; 
   //        }
   //     }

starts up the main window

        m.start(false, false, false);

loads the KuraFace

        m.loadModel("KuraFace", m.getDemoClassName("KuraFace"));


        //Main.getScheduler().playRequest();

instantiates itself -- class behaviour specified in the constructor

        try {

           StartAS startAS = new StartAS();
        }

        catch(IOException io) {

           System.out.println("IO Exception: " + io);
        }

      }

StartAS class constructor -- specifies behaviour for receiving values

      public StartAS() throws IOException
      {

         ServerSocket serverSocket = null;

tries to listen on port 4444 for socket connection

         try {

             serverSocket = new ServerSocket(4444);
         }

         catch (IOException e) {

             System.err.println("Could not listen on port: 4444.");
             System.exit(1);
         }

Infinite loop - continuously waiting for connection

         while( true ) {

                 Socket clientSocket = null;

waits for connection

                 try {

                     clientSocket = serverSocket.accept();
                 }

                 catch (IOException e) {

                         System.err.println("Accept failed.");
                         System.exit(1);
                 }

grabs data from client socket

                 PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(
                                         new InputStreamReader(
                                         clientSocket.getInputStream()));
                 String inputLine;

                 while ((inputLine = in.readLine()) != null) {

                      if (inputLine.equals( "Bye." )) {

                         break;
                      }

                      else if( inputLine.matches ( "(-?\\d+\\.?\\d*;){8}")) {

                         System.out.println( "Received from client: " + inputLine );
                         out.println( "Server received: " + inputLine );

set received values as properties, to be sent to the KuraFace model

                         PCmults = inputLine.split (";");
                         System.setProperty( "mult1", PCmults[0]);
                         System.setProperty( "mult2", PCmults[1]);
                         System.setProperty( "mult3", PCmults[2]);
                         System.setProperty( "mult4", PCmults[3]);
                         System.setProperty( "mult5", PCmults[4]);
                         System.setProperty( "mult6", PCmults[5]);
                         System.setProperty( "mult7", PCmults[6]);
                         System.setProperty( "mult8", PCmults[7]);

refresh the workspace, which will cause new values to be loaded to the KuraFace

                         m.getWorkspace ().advance (0, 1);
                         m.rerender ();
                      }

                      else {

                         out.println( "Invalid format sent - should be a concatenation of 8 (float followed by semicolon)");
                      }
                 }

                 out.close();
                 in.close();
                 clientSocket.close();
                 // serverSocket.close();
         }    
     }          

     static Main m;
     String PCmults[] = new String[8];
   }

The next step is to create a client socket that will send values to StartAS.