/* * Copyright (C) 2013 gujicheng * * Licensed under the GPL License Version 2.0; * you may not use this file except in compliance with the License. * * If you have any question, please contact me. * ************************************************************************* ** Author information ** ************************************************************************* ** Email: [email protected] ** ** QQ : 29600731 ** ** Weibo: http://weibo.com/gujicheng197 ** ************************************************************************* */ package com.libra.sinvoice; import android.media.AudioManager; import android.media.AudioTrack; import com.libra.sinvoice.Buffer.BufferData; /** * * @ClassName: com.libra.sinvoice.PcmPlayer * @Description: PCM播放器 * @author zhaokaiqiang * @date 2014-11-15 下午1:10:18 * */ public class PcmPlayer { private final static String TAG = "PcmPlayer"; private final static int STATE_START = 1; private final static int STATE_STOP = 2; // 播放状态,用于控制播放或者是停止 private int mState; private AudioTrack audioTrack; // 已经播放过的字节长度 private long playedLen; private PcmListener pcmListener; private PcmCallback playerCallback; public static interface PcmListener { void onPcmPlayStart(); void onPcmPlayStop(); } public static interface PcmCallback { BufferData getPcmPlayBuffer(); void freePcmPlayData(BufferData data); } public PcmPlayer(PcmCallback callback, int sampleRate, int channel, int format, int bufferSize) { playerCallback = callback; // 初始化AudioTrack对象(音频流类型,采样率,通道,格式,缓冲区大小,模式) audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channel, format, bufferSize, AudioTrack.MODE_STREAM); mState = STATE_STOP; } public void setListener(PcmListener listener) { pcmListener = listener; } public void start() { if (STATE_STOP == mState && null != audioTrack) { mState = STATE_START; playedLen = 0; if (null != playerCallback) { if (null != pcmListener) { pcmListener.onPcmPlayStart(); } while (STATE_START == mState) { // 获取要播放的字节数据 BufferData data = playerCallback.getPcmPlayBuffer(); if (null != data) { if (null != data.byteData) { // 首次进入,开始播放声音 if (0 == playedLen) { audioTrack.play(); } // 设置要播放的字节数据 int len = audioTrack.write(data.byteData, 0, data.getFilledSize()); playedLen += len; // 释放数据 playerCallback.freePcmPlayData(data); } else { LogHelper.d(TAG, "it is the end of input, so need stop"); break; } } else { LogHelper.d(TAG, "get null data"); break; } } if (STATE_STOP == mState) { audioTrack.pause(); audioTrack.flush(); audioTrack.stop(); audioTrack.release(); } if (null != pcmListener) { pcmListener.onPcmPlayStop(); } } else { throw new IllegalArgumentException("PcmCallback can't be null"); } } } public void stop() { if (STATE_START == mState && null != audioTrack) { mState = STATE_STOP; } } }