求解决pcm播放问题
来源:互联网 发布:python安装包怎么下载 编辑:程序博客网 时间:2024/06/05 10:57
7~LHGL`((@G{{1GD2VLVL.jpg (30.48 KB, 下载次数: 0)
工程图
使用audio来录音,使用AudioTrack来播放,发现播放出来的声音是吱吱的那种杂音。这是怎么回事呢?录音代码中采样率8000的时候播放pcm数据是吱吱的声音;但是44100的时候没有声音;怎么解决播放录的声音;
public class AudioPlayerDemoActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */
private TextView mTextViewState; // 播放状态
private Button mBtnPlayButton; // 播放
private Button mBtnPauseButton; // 暂停
private Button mBtnStopButton; // 停止
private AudioPlayer mAudioPlayer; // 播放器
private Handler mHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
initLogic();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mAudioPlayer.release();
}
public void initView()
{
mTextViewState = (TextView) findViewById(R.id.tvPlayState);
mBtnPlayButton = (Button) findViewById(R.id.buttonPlay);
mBtnPlayButton.setOnClickListener(this);
mBtnPauseButton = (Button) findViewById(R.id.buttonPause);
mBtnPauseButton.setOnClickListener(this);
mBtnStopButton = (Button) findViewById(R.id.buttonStop);
mBtnStopButton.setOnClickListener(this);
}
public void initLogic()
{
mHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch(msg.what)
{
case AudioPlayer.STATE_MSG_ID:
showState((Integer)msg.obj);
break;
}
}
};
mAudioPlayer = new AudioPlayer(mHandler);
// 获取音频参数
AudioParam audioParam = getAudioParam();
mAudioPlayer.setAudioParam(audioParam);
// 获取音频数据
byte[] data = getPCMData();
mAudioPlayer.setDataSource(data);
// 音频源就绪
mAudioPlayer.prepare();
if (data == null)
{
mTextViewState.setText(filePath + ":该路径下不存在文件!");
}
}
@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch(view.getId())
{
case R.id.buttonPlay:
play();
break;
case R.id.buttonPause:
pause();
break;
case R.id.buttonStop:
stop();
break;
}
}
public void play()
{
mAudioPlayer.play();
}
public void pause()
{
mAudioPlayer.pause();
}
public void stop()
{
mAudioPlayer.stop();
}
public void showState(int state)
{
String showString = "";
switch(state)
{
case PlayState.MPS_UNINIT:
showString = "MPS_UNINIT";
break;
case PlayState.MPS_PREPARE:
showString = "MPS_PREPARE";
break;
case PlayState.MPS_PLAYING:
showString = "MPS_PLAYING";
break;
case PlayState.MPS_PAUSE:
showString = "MPS_PAUSE";
break;
}
showState(showString);
}
public void showState(String str)
{
mTextViewState.setText(str);
}
/*
* 获得PCM音频数据参数
*/
public AudioParam getAudioParam()
{
AudioParam audioParam = new AudioParam();
audioParam.mFrequency = 44100;
audioParam.mChannel = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
audioParam.mSampBit = AudioFormat.ENCODING_PCM_16BIT;
return audioParam;
}
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/testmusic.pcm";
/*
* 获得PCM音频数据
*/
public byte[] getPCMData()
{
File file = new File(filePath);
if (file == null){
return null;
}
FileInputStream inStream;
try {
inStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
byte[] data_pack = null;
if (inStream != null){
long size = file.length();
data_pack = new byte[(int) size];
try {
inStream.read(data_pack);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
return data_pack;
}
}
下面这个是AudioPlaye
package com.genius.demo;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;
public class AudioPlayer implements IPlayComplete{
private final static String TAG = "AudioPlayer";
public final static int STATE_MSG_ID = 0x0010;
private Handler mHandler;
private AudioParam mAudioParam; // 音频参数
private byte[] mData; // 音频数据
private AudioTrack mAudioTrack; // AudioTrack对象
private boolean mBReady = false; // 播放源是否就绪
private PlayAudioThread mPlayAudioThread; // 播放线程
public AudioPlayer(Handler handler)
{
mHandler = handler;
}
public AudioPlayer(Handler handler,AudioParam audioParam)
{
mHandler = handler;
setAudioParam(audioParam);
}
/*
* 设置音频参数
*/
public void setAudioParam(AudioParam audioParam)
{
mAudioParam = audioParam;
}
/*
* 设置音频源
*/
public void setDataSource(byte[] data)
{
mData = data;
}
/*
* 就绪播放源
*/
public boolean prepare()
{
if (mData == null || mAudioParam == null)
{
return false;
}
if (mBReady == true)
{
return true;
}
try {
createAudioTrack();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
mBReady = true;
setPlayState(PlayState.MPS_PREPARE);
return true;
}
/*
* 释放播放源
*/
public boolean release()
{
stop();
releaseAudioTrack();
mBReady = false;
setPlayState(PlayState.MPS_UNINIT);
return true;
}
/*
* 播放
*/
public boolean play()
{
if (mBReady == false)
{
return false;
}
switch(mPlayState)
{
case PlayState.MPS_PREPARE:
mPlayOffset = 0;
setPlayState(PlayState.MPS_PLAYING);
startThread();
break;
case PlayState.MPS_PAUSE:
setPlayState(PlayState.MPS_PLAYING);
startThread();
break;
}
return true;
}
/*
* 暂停
*/
public boolean pause()
{
if (mBReady == false)
{
return false;
}
if (mPlayState == PlayState.MPS_PLAYING)
{
setPlayState(PlayState.MPS_PAUSE);
stopThread();
}
return true;
}
/*
* 停止
*/
public boolean stop()
{
if (mBReady == false)
{
return false;
}
setPlayState(PlayState.MPS_PREPARE);
stopThread();
return true;
}
private synchronized void setPlayState(int state)
{
mPlayState = state;
if (mHandler != null)
{
Message msg = mHandler.obtainMessage(STATE_MSG_ID);
msg.obj = mPlayState;
msg.sendToTarget();
}
}
private void createAudioTrack() throws Exception
{
// 获得构建对象的最小缓冲区大小 一般情况 minBufferSize 会导致播出吱吱声音。
int minBufSize = AudioTrack.getMinBufferSize(mAudioParam.mFrequency,
mAudioParam.mChannel,
mAudioParam.mSampBit);
mPrimePlaySize = minBufSize * 2;
Log.d(TAG, "mPrimePlaySize = " + mPrimePlaySize);
// STREAM_ALARM:警告声
// STREAM_MUSCI:音乐声,例如music等
// STREAM_RING:铃声
// STREAM_SYSTEM:系统声音
// STREAM_VOCIE_CALL:电话声音
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
mAudioParam.mFrequency,
mAudioParam.mChannel,
mAudioParam.mSampBit,
minBufSize,
AudioTrack.MODE_STREAM);
// AudioTrack中有MODE_STATIC和MODE_STREAM两种分类。
// STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。
// 这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。
// 这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
// 而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,
// 后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。
// 这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用。
}
private void releaseAudioTrack(){
if (mAudioTrack != null){
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}
}
private void startThread()
{
if (mPlayAudioThread == null)
{
mThreadExitFlag = false;
mPlayAudioThread = new PlayAudioThread();
mPlayAudioThread.start();
}
}
private void stopThread()
{
if (mPlayAudioThread != null)
{
mThreadExitFlag = true;
mPlayAudioThread = null;
}
}
private boolean mThreadExitFlag = false; // 线程退出标志
private int mPrimePlaySize = 0; // 较优播放块大小
private int mPlayOffset = 0; // 当前播放位置
private int mPlayState = 0; // 当前播放状态
/*
* 播放音频的线程
*/
class PlayAudioThread extends Thread
{
@Override
public void run() {
// TODO Auto-generated method stub
Log.d(TAG, "PlayAudioThread run mPlayOffset = " + mPlayOffset);
mAudioTrack.play();
while(true)
{
if (mThreadExitFlag == true)
{
break;
}
try {
int size = mAudioTrack.write(mData, mPlayOffset, mPrimePlaySize);
mPlayOffset += mPrimePlaySize;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
AudioPlayer.this.onPlayComplete();
break;
}
if (mPlayOffset >= mData.length)
{
AudioPlayer.this.onPlayComplete();
break;
}
}
mAudioTrack.stop();
Log.d(TAG, "PlayAudioThread complete...");
}
}
@Override
public void onPlayComplete() {
// TODO Auto-generated method stub
mPlayAudioThread = null;
if (mPlayState != PlayState.MPS_PAUSE)
{
setPlayState(PlayState.MPS_PREPARE);
}
}
}
···············java代码 AudioParam······················
package com.genius.demo;
public class AudioParam {
int mFrequency; // 采样率
int mChannel; // 声道
int mSampBit; // 采样精度
}
··············java代码 IPlayComplete ···················
package com.genius.demo;
public interface IPlayComplete {
public void onPlayComplete();
}
··················java代码 PlayState·····················
package com.genius.demo;
public interface PlayState {
public static final int MPS_UNINIT = 0; // 未就绪
public static final int MPS_PREPARE = 1; // 准备就绪(停止)
public static final int MPS_PLAYING = 2; // 播放中
public static final int MPS_PAUSE = 3; // 暂停
}
- 求解决pcm播放问题
- ios之audio unit的录音和播放一起,解决audioqueue播放PCM延迟问题
- 播放PCM
- WaveOutXX 播放PCM流
- ios播放PCM数据
- ios播放PCM数据
- IOS播放PCM数据
- IOS播放PCM数据
- ios播放PCM数据
- PCM文件播放器
- PCM文件播放器
- android audiotrack 播放pcm
- SDL2播放PCM
- XAudio2播放PCM
- sdl播放pcm文件
- VLC 播放PCM音频文件
- 求解决,拨号问题
- openal播放pcm缓存数据
- iis设置开启GZIP网页压缩功能
- java递归算法实现
- dynamic_cast
- linux常用命令
- Android 自定义控件☞添加attr属性
- 求解决pcm播放问题
- SQLSERVER 存储过程 语法
- python对象的私有封装
- KVO的概述与使用
- 使用smartupload组件上传图片(jsp+servlet)
- 安卓中利用OnGestureListener对控件进行手势滑动事件的处理
- 给datagridview添加一个自定义列类型-日期类型
- Android 方向感应器实现指南针
- 男银的魅力在于力量与智慧。女银的魅力在于微笑与气质。