MCS 파일 재생하기

ClipPlayer 클래스를 사용하면 MCS 파일을 재생할 수 있는데, 애플리케이션에 포함된 MCS 파일을 재생할 수도 있고 서버에 있는 MCS 파일을 재생할 수도 있다. MCS 파일을 서버에 두는 경우는 스마트 폰이 네트워크에 연결되어 있어야 한다는 단점이 있지만 애플리케이션을 교체하지 않고도 로봇의 모션을 언제든지 변경할 수 있다는 장점이 있다.

01. 애플리케이션에 포함된 MCS 파일 재생하기

MCS 파일을 애플리케이션에 포함하기 위해 그림 1과 같이 res 폴더에 raw 폴더를 새로 만들고, raw 폴더에 제작된 MCS 파일을 넣는다.

그림 1. MCS 파일 넣기

MCS 파일을 재생하기 위해 Activity 클래스의 onDestroy() 메소드를 상속받아 새로 구현하자. 프로젝트에 스마트 로봇 라이브러리를 포함하는 것을 잊지 않기를 바란다.

 public class SampleActivity extends Activity
 {
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();
     }
 }

ClipPlayer 클래스의 obtain(Context context, int clipPlayerId) 메소드를 통해 클립 재생기 객체를 얻을 수 있는데, clipPlayerId에는 클립 재생기를 구분하기 위한 숫자를 입력하면 된다. 여기서는 0을 입력하였다.

 public class SampleActivity extends Activity
 {
     private ClipPlayer mClipPlayer;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0); // 클립 재생기 객체를 얻는다.
         mClipPlayer.open(getPackageName(), R.raw.test); // MCS 파일을 연다.
         mClipPlayer.play(); // MCS 파일을 재생한다.
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop(); // MCS 파일의 재생을 중지한다.
         mClipPlayer.close(); // MCS 파일을 닫는다.
     }
 }

onCreate(Bundle savedInstanceState) 메소드에서 클립 재생기를 얻어서 파일을 열고 재생하며, onDestroy() 메소드에서 재생을 중지하고 파일을 닫았지만 어디에서 해도 상관은 없다. 파일을 미리 열어 두고 필요한 시점에 재생하여도 되고, 버튼을 누르면 재생하여도 된다. 여기서는 간단하게 하기 위해 onDestroy() 메소드에서 파일을 닫았지만 onDestroy() 메소드가 항상 호출되는 것은 아니므로 애플리케이션에 따라 onBackPressed() 메소드 등에서 파일을 닫을 수도 있다. 애플리케이션을 종료하기 전에 열려 있는 MCS 파일을 모두 닫아야 한다는 것만 잊지 않도록 하자. 프로그램을 실행하면 MCS 파일이 재생될 것이다.

MCS 파일을 열 때, 앞의 예에서와 같이 리소스 ID로 열 수도 있지만 리소스 이름으로 열 수도 있다. 리소스 이름은 MCS 파일의 확장자를 제외한 파일 이름이다. 앞의 예에서는 MCS 파일이 test.mcs이므로 리소스 이름은 "test"이다.

 public class SampleActivity extends Activity
 {
     private ClipPlayer mClipPlayer;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open(getPackageName(), "test"); // MCS 파일을 연다.
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }
 }

02. 다른 애플리케이션에 포함된 MCS 파일 재생하기

작업 중인 애플리케이션에 포함된 MCS 파일 뿐만 아니라 다른 애플리케이션에 포함된 MCS 파일도 재생할 수 있다. MCS 파일을 열 때, 패키지 이름에 해당 애플리케이션의 패키지 이름을 입력하면 된다. 여기서는 다른 애플리케이션의 패키지 이름을 "com.sample.other"라고 가정하였다.

 public class SampleActivity extends Activity
 {
     private ClipPlayer mClipPlayer;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open("com.sample.other", "test"); // MCS 파일을 연다.
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }
 }

03. 서버에 있는 MCS 파일 재생하기

서버에 있는 MCS 파일을 재생하기 위해서는 MCS 파일을 열 때, MCS 파일의 URL 경로를 입력하면 된다. 여기서는 MCS 파일이 http://www.sample.com/test.mcs에 있다고 가정하였다.

 public class SampleActivity extends Activity
 {
     private ClipPlayer mClipPlayer;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open("http://www.sample.com/test.mcs"); // MCS 파일을 연다.
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }
 }

04. MCS 파일의 호환

알버트 로봇을 위해 만들어진 MCS 파일은 알파 로봇에서도 재생되며, 알파 로봇을 위해 만들어진 MCS 파일은 알버트 로봇에서도 재생된다. 즉, 알버트 로봇과 알파 로봇은 MCS 파일을 서로 호환하여 사용할 수 있다.

다만 알버트 로봇에는 앞쪽 LED와 몸통 LED, 두 개의 디바이스가 더 있기 때문에, 알버트 로봇을 위해 만들어진 MCS 파일에서 앞쪽 LED와 몸통 LED를 제어한다면 알파 로봇에서는 해당되는 디바이스가 없어서 이 데이터가 무시된다. 마찬가지로 알파 로봇을 위해 만들어진 MCS 파일에는 앞쪽 LED와 몸통 LED를 제어하는 데이터가 없기 때문에 알버트 로봇에서는 해당되는 디바이스가 제어되지 않는다.

05. 입 움직임 표현하기

알버트 로봇에는 EFFECTOR_LIP 디바이스가 있고, 타임라인 모션 에디터에 Lip 트랙이 있다는 것을 기억할 것이다. 로보이드 스튜디오에서 Lip 트랙에 제어점을 생성하거나 Voice 트랙에 제어점을 생성하면 MCS 파일이 재생될 때 입의 움직임 데이터가 EFFECTOR_LIP 디바이스에 쓰여진다. 이 데이터를 읽어 몸통 LED로 표현해 보도록 하자.

알버트 로봇의 디바이스를 직접 제어해야 하므로 RobotActivity 클래스를 상속한 액티비티를 만들고, onInitialized(Robot) 메소드와 onExecute() 메소드를 상속받아 새로 구현하자. 프로젝트에 스마트 로봇 라이브러리를 포함하는 것을 잊지 않기를 바란다.

 public class SampleActivity extends RobotActivity
 {
     private ClipPlayer mClipPlayer;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open(getPackageName(), R.raw.test); // MCS 파일을 연다.
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }

     @Override
     public void onInitialized(Robot robot)
     {
     }

     @Override
     public void onExecute()
     {
     }
 }

알버트 로봇에는 입의 크기를 나타내는 디바이스로 EFFECTOR_LIP이 있다. 입의 크기 데이터는 0부터 100까지의 값을 가지는데, 입의 크기를 %로 나타낸다.

 public class SampleActivity extends RobotActivity
 {
     private ClipPlayer mClipPlayer;
     private Device mLipDevice;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open(getPackageName(), R.raw.test);
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }

     @Override
     public void onInitialized(Robot robot)
     {
         mLipDevice = robot.findDeviceById(Albert.EFFECTOR_LIP);
     }

     @Override
     public void onExecute()
     {
         int lip = mLipDevice.read();
     }
 }

알버트 로봇에는 몸통 LED의 밝기를 나타내는 디바이스로 EFFECTOR_BODY_LED가 있다. 몸통 LED의 밝기 데이터는 0부터 100까지의 값을 가지는데, 밝기를 %로 나타낸다.

 public class SampleActivity extends RobotActivity
 {
     private ClipPlayer mClipPlayer;
     private Device mLipDevice;
     private Device mBodyLEDDevice;

     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         mClipPlayer = ClipPlayer.obtain(this, 0);
         mClipPlayer.open(getPackageName(), R.raw.test);
         mClipPlayer.play();
     }

     @Override
     public void onDestroy()
     {
         super.onDestroy();

         mClipPlayer.stop();
         mClipPlayer.close();
     }

     @Override
     public void onInitialized(Robot robot)
     {
         mLipDevice = robot.findDeviceById(Albert.EFFECTOR_LIP);
         mBodyLEDDevice = robot.findDeviceById(Albert.EFFECTOR_BODY_LED);
     }

     @Override
     public void onExecute()
     {
         int lip = mLipDevice.read();
         mBodyLEDDevice.write(lip);
     }
 }