読者です 読者をやめる 読者になる 読者になる

AndroidでWAVEファイル再生

AndroidでWAVEファイルが再生できたのでメモ

androidでWAVEファイル再生
以下のクラスでWAVEファイルを再生できた

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.IBinder;
import android.util.Log;


public class MyAudioTrackService extends Service{
	final static String TAG = "MyAudioTrackService";

	AudioTrack audioTrack; //再生用のクラス
    private byte[] playByteData = new byte[4096];
    private short[] playShortData = new short[2048];
    private int playBufSize; //再生用バッファサイズ
    private FileInputStream playStream ;//ファイル読み込みよう

	@Override
	public IBinder onBind(Intent intent) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "onCreate");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "onStartCommand");
		playRecord();
		return START_STICKY;
	}

	@Override
	public void onStart(Intent intent, int startId) {
		playRecord();
		Log.d(TAG, "onStart");
	};

	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "onDestroy");
	}

	///////////////////////////////////////再生用///////////////////////////////////////////
	private void playRecord(){
		if(audioTrack != null && audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING){
			audioTrack.stop();
		}else{
			playInit();
			File playFile = new File(SoundDefine.filePath);

			//playByteData = new byte[(int) playFile.length()];


			// バッファを3つエンキュー
			try {
				playStream = new FileInputStream(playFile);

				//3フレーム分書き込まないと再生できなかった
				for(int i=0; i<3; i++){
					playStream.read(playByteData); // byteで読む
					byte2short(playShortData, playByteData);
					audioTrack.write(playShortData, 0, playShortData.length);
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			audioTrack.play();
		}
	}

	/**
	* 再生用オーディオトラック初期化
	*/
	private void playInit(){
		//必要なバッファサイズの計算
		playBufSize = AudioTrack.getMinBufferSize(SoundDefine.SAMPLING_RATE,  //バッファサイズ
		AudioFormat.CHANNEL_OUT_MONO,  //チャンネル
		AudioFormat.ENCODING_PCM_16BIT); //エンコーディング形式 pcm16ビット


		//AudioTrackインスタンス作成
		audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, //ストリームタイプ
				SoundDefine.SAMPLING_RATE, //サンプリング周波数
		AudioFormat.CHANNEL_OUT_MONO, //チャネル
		AudioFormat.ENCODING_PCM_16BIT,  //オーディオフォーマット
		playBufSize, //バッファサイズ
		AudioTrack.MODE_STREAM); //モード

		//FRAMESIZE分再生ごとに通知をおこないonPeriodicNotification実行
		audioTrack.setPositionNotificationPeriod(playShortData.length / 2 );

		//コールバックの指定
		audioTrack.setPlaybackPositionUpdateListener(new AudioTrack.OnPlaybackPositionUpdateListener(){
			//コールバック内でバッファをエンキュー
			@Override
			public void onPeriodicNotification(AudioTrack track){
				try {
					int endFlg = playStream.read(playByteData); // byteで読む 最後まで読み込んだ場合は戻り値が-1になる
					if(endFlg != -1){
						byte2short(playShortData, playByteData);
						audioTrack.write(playShortData, 0, playShortData.length);
						//audioTrack.write(playByteData, 0, playByteData.length);
						Log.d(TAG, "audioWrite");
					}else{
						audioTrack.stop();
					}
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			//再生完了時のコールバック
			@Override
			public void onMarkerReached(AudioTrack track) {
				// TODO Auto-generated method stub
				//再生完了ならonMarkerReachedが呼ばれるはずだが自作のWAVEファイルだと呼ばれなかった。
				audioTrack.stop();
				Log.d(TAG, "audioStop");
			}
		});
	}

	//byteデータ列をshortのオーディオサンプル列に変換
	void byte2short(short data[], byte bdata[]){
		int i;
		for(i = 0; i < bdata.length / 2; i++){
			// リトルエンディアン
			data[i] = (short) ((short) bdata[2 * i] + (short) bdata[2 * i + 1] * 256);
		}
	}
}