コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

サウンドの再生

Androidのサウンドの再生について勉強してみました。防備録としてブログに書いておきます。
Androidのサウンドの再生は、MediaPlayerというクラスを用いてできるようです。MediaPlayerをいろいろと触ってみましたが、何かしっくり来ないので、SoundCommandというクラスを自作してみました。java初心者なので、変なことをやっているかもしれません。

MediaPlayerで気に入らないところ

もしかしたら、私の勉強不足なだけで、できるのかもしれません。

    • stop()すると曲の頭に戻らない。stop()して曲の頭に戻したいときには、setDataSource()をやり直さなければならないのかな?不明。
    • start()で多重再生ができない。
    • pause()して曲の頭からスタートできない。

ここら辺を考えて、以下のようなクラスを書いてみました。

import java.io.IOException;
import android.media.MediaPlayer;
//*************************************************
// サウンドを鳴らすクラスを作ってみました
//*************************************************
public class SoundCommand {
  private int prSubChannelNum = 0;      //サブチャネル番号
  private boolean  prBGMflg = false;    //BGMフラグ      
  private MediaPlayer[] prMediaPlr = new MediaPlayer[4];
  private int prPausePosition = 0;
  
  public void setSoundFile(String filename, boolean bgmFlg){
    this.prBGMflg = bgmFlg;
    this.prSubChannelNum = 0;
    
    try {
      if( bgmFlg==false ){
        for( int i=0; i<4; i++ ){
          if( prMediaPlr[i]==null ){  prMediaPlr[i] = new MediaPlayer();  }
          prMediaPlr[i].reset();
          prMediaPlr[i].setDataSource( filename );
          prMediaPlr[i].prepare();
        }
      }
      else{
        if( prMediaPlr[0]==null ){  prMediaPlr[0] = new MediaPlayer();  }
        prMediaPlr[0].reset();
        prMediaPlr[0].setDataSource( filename );
        prMediaPlr[0].prepare();
      }
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  
  //*************************************************
  // 再生開始します
  //*************************************************
  public void start(){
    if( prMediaPlr[0]==null ){  return;    }

    if( this.prBGMflg==true ){
      if( prMediaPlr[0].isPlaying()==false ){
        prMediaPlr[0].seekTo(prPausePosition);
        prMediaPlr[0].start();
      }
    }
    else{
      this.prSubChannelNum++;
      if( this.prSubChannelNum>3 ){  this.prSubChannelNum = 0;  }
      prMediaPlr[this.prSubChannelNum].seekTo(prPausePosition);
      prMediaPlr[this.prSubChannelNum].start();
    }
  }
  
  //*************************************************
  // 再生停止します
  //*************************************************
  public void stop(){
    if( prMediaPlr[0]==null ){  return;    }

    if( this.prBGMflg==true ){
      if( prMediaPlr[0].isPlaying()==true ){
        prMediaPlr[0].seekTo(prMediaPlr[0].getDuration());
        prPausePosition = 0;
      }
    }
    else{
      for( int i=0; i<4; i++ ){
        if( prMediaPlr[i].isPlaying()==true ){
          prMediaPlr[i].seekTo(prMediaPlr[i].getDuration());
        }
      }
      prPausePosition = 0;
    }
  }
  
  //*************************************************
  // 頭から再生します
  //*************************************************
  public void repeat(){
    if( prMediaPlr[0]==null ){  return;    }

    int num = 0; 
    if( this.prBGMflg==false ){  num = this.prSubChannelNum;    }
    if( prMediaPlr[num].isPlaying()==true ){
      prMediaPlr[num].seekTo(0);
    }
    else{
      prMediaPlr[num].seekTo(prMediaPlr[num].getDuration());
      prMediaPlr[num].start();
      prMediaPlr[num].start();
    }
  }
     
  //*************************************************
  // 再生中のサウンドを一時停止します
  //*************************************************
  public void pause(){
    if( prMediaPlr[0]==null ){  return;    }

    int num = 0; 
    if( this.prBGMflg==false ){  num = this.prSubChannelNum;    }
    
    if( prMediaPlr[num].isPlaying()==true ){
      //prMediaPlr[num].pause();
      prPausePosition = prMediaPlr[num].getCurrentPosition();
      prMediaPlr[num].seekTo(prMediaPlr[num].getDuration());
    }
     }
  //*************************************************
  // ループセットします
  //*************************************************
  public void setLoop(boolean loopflg){
    if( prMediaPlr[0]==null ){  return;    }

    if( this.prBGMflg==true ){
      prMediaPlr[0].setLooping(loopflg);
    }
    else{
      for( int i=0; i<4; i++ ){
        prMediaPlr[i].setLooping(loopflg);
      }
    }
  }
}

曲の多重再生

曲の多重再生には、フラグを用意しました。BGMフラグがFalseの時に、多重再生するようにしています。多重再生とは、音が鳴っているときに、再生スタートすると先の音が鳴ったまま、さらに鳴り始めることをいいます。MediaPlayerを4個配列を取っており、4重音まで多重になるように設計しています。

private MediaPlayer[] prMediaPlr = new MediaPlayer[4];

BGMフラグがTrueの場合は、多重再生しないので、音が鳴っているときに、start()しても、再生は開始されません。音が止まっているときのみ再生されます。ただし、repeat()の場合は、曲が鳴っていても、鳴っていなくても、頭から再生されます。

使い方

SoundCommandのインスタンスを作って、setSoundFile()で、サウンドファイル名とBGMフラグをセットして、start();で鳴ります。

  SoundCommand sc = new SoundCommand();
  sc.setSoundFile("/sdcard/ogg/test0.ogg", true);
  sc.start();

setLoop(true)とすると、setLoop(false)しない限り、曲は止まりません。仕様です(^^;。

この勉強結果をもとに、Luaridaにサウンドコマンドを組み込んでみたいと思います。