サイト移転のお知らせ:http://techbooster.org/に移転しました

AudioTrackを使ってWAVEデータを再生する

1月 1, 2011   //   by kseto   //   マルチメディア  //  No Comments

あけましておめでとうございます!
2011年もTechBoosterを宜しくお願い致します。

さて、2011年最初のHow To AndroidはAudioTrackを使ってWAVEデータを再生する方法についてご紹介します。

詳細はつづきからどうぞ。

AudioTrackクラスではバイトデータをオーディオハードウェアに直接書き込むことができるので、
MediaPlayerクラスと比べて高速に音を鳴らすことができます。
ゲームやGUIの効果音のような、リアルタイムに音を出したいというような用途に向いています。

コンストラクタ

AudioTrackクラスのコンストラクタは以下のようになっています。

AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId)
streamType ストリームタイプを指定します。
sampleRateInHz サンプルレートを指定します。
channelConfig オーディオチャネルを指定します。
audioFormat オーディオフォーマットを指定します。ENCODING_PCM_16BITとENCODING_PCM_8BITの2つがあります。
bufferSizeInBytes オーディオデータのバッファサイズを指定します。
mode STREAMモードかSTATICモードかいずれかを選択します。詳細は後述します。
sessionId オーディオセッションIDを指定します。

STREAMモードとSTATICモード

AudioTrackクラスは以下の2つのモードで動作します。

  • STREAMモード:
    メモリに収まらない大きな音声データを再生したい場合、音声データを一定量ずつ、逐一ハードウェアに出力します。
  • STATICモード:
    メモリに収まる程度の小さな音声データは予めメモり領域上に置いておいて、それを必要なときにハードウェアに出力します。

サンプルコード

以下はAudioTrackクラスを使ってSDカードに保存してあるWAVEファイルを鳴らすサンプルです。
WAVEファイルはサンプリングレート44100Hz、オーディオチャネル2ch、16bitのものを使っています。
大きなバイトデータになりますので、STREAMモードを使います。

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

	// ボタンのインスタンスを作成
	play_button = (Button) findViewById(R.id.Button01);
	stop_button = (Button) findViewById(R.id.Button02);

	// WAVEファイルのFileインスタンスを作成
	file = new File("/sdcard/strings.wav");
	
	// WAVEファイルのサイズを取得
	byteData = new byte[(int) file.length()];

	// WAVEファイルをロード
	FileInputStream in = null;
	try {
		in = new FileInputStream(file);
		in.read(byteData);
		in.close();
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	// 再生用初期化処理
	initialize();

	// プレイボタン
	play_button.setOnClickListener(new OnClickListener() {
		public void onClick(View v) {
			// 再生用スレッドを起こす
			play_thread.start();
		}
	});

	// ストップボタン
	stop_button.setOnClickListener(new OnClickListener() {
		public void onClick(View v) {
			// 再生中なら停止させる
			if (myAT.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
				myAT.stop();
				play_thread = null;
				initialize();
			}
		}
	});
}

// 再生用初期化処理
void initialize() {
	// 必要となるバッファサイズを計算
	bufSize = android.media.AudioTrack.getMinBufferSize(44100,
			AudioFormat.CHANNEL_CONFIGURATION_MONO,
			AudioFormat.ENCODING_PCM_16BIT);
	
	// AudioTrackインスタンス作成
	myAT = new AudioTrack(AudioManager.STREAM_MUSIC,
			44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
			AudioFormat.ENCODING_PCM_16BIT, bufSize,
			AudioTrack.MODE_STREAM);
	
	// スレッドインスタンス作成
	play_thread = new Thread(this);
}

// 再生用スレッド処理
public void run() {
	if (myAT != null) {
		// 再生開始
		myAT.play();
		myAT.write(byteData, 0, byteData.length);
	}
}

処理としては、SDカードに保存しているWAVEファイル用のFileインスタンスを作成し、WAVEファイルのバイトデータをFileInputStreamにロードします(10-26行目)
バイトデータをロードしたらAudioTrackインスタンスの初期化処理を行います(29行目, 52-67行目)。
ここで、WAVEファイルのサンプリングレートなどの情報をもとに必要なバッファサイズを計算し、AudioTrackインスタンスを作成します。
あとはボタンが押されたら再生を開始させます(35行目, 69-76行目)。
writeメソッドはバイトデータの書き込みが終わるまでブロックしてしまうのでスレッドで実行するようにしています。

関連する記事:

Sponsored Link

Comments are closed.

技術書新刊 発売中

アンドロイドアカデミアには、CIやテスト、互換検証など実務に生きるノウハウをあつめています

技術書新刊 発売中

Android Next!はAndroid 7.0に対応したはじめての技術書です!


The Web Explorer 2はCSSの中央寄せやWebAudioなど未来を読み解く一冊です


Revised TypeScript in DefinitelylandはTypeScript 2.0(β)に対応した解説書です。インストールから型定義まで幅広くサポートしています


技術書をかこう!はエンジニアらしい執筆環境を構築、HowTo本です