Refrence

  • https://blog.csdn.net/qq_15255121/article/details/115168456
  • https://blog.csdn.net/qq_15255121/article/details/118964421

我们要想对wav文件格式操作,我们就要了解wav的文件格式。

由上图可知:

  • 第8到11字节 代表当前是wave格式也就是wav格式
  • 第20-21字节 代表当前的音频数据是什么格式 如果是1代表是pcm格式
  • 第24-28字节,代表当前的采样率
  • 第34-35字节,代表当前的采样大小(位深)
  • 第44字节开始,是我们真实的数据

通过上面的分析我们可以知道,wav只是把pcm包装了一下,我们可以从头中得到采样率 采样大小 位深等参数。并没有对音频数据进行压缩。

我们再结合 https://blog.csdn.net/qq_15255121/article/details/118964421 就可以实现对wav文件格式的播放。

package com.yuanxuzhen.androidmedia.audio;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.RequiresApi;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/******* wav格式可以参考https://blog.csdn.net/qq_15255121/article/details/115168456** ****/
public class WavPlayer {private static volatile WavPlayer instance;private AudioTrack mAudioTrack;private int audioFormat;private int buffersize;private ExecutorService executorService;private DataInputStream inputStream;private static final  int HEADER_SIZE = 44;private static final  int AUDIO_FORMAT_POSITION = 20;private static final  int AUDIO_NUM_CHANNEL_POSITION = 22;private static final  int AUDIO_BIT_PERSAMPLE_POSITION = 34;private static final  int AUDIO_SAMPLE_RATE_POSITION = 24;public class WavData{int channelMask = AudioFormat.CHANNEL_OUT_MONO;int sampleRate = 48000;int audioFormatEncodeing = AudioFormat.ENCODING_PCM_FLOAT;}private WavPlayer(){}public static WavPlayer getInstance(){if(instance == null){synchronized (WavPlayer.class){if(instance == null){instance = new WavPlayer();}}}return instance;}public WavData getInfo(String path){WavData info = new WavData();try{int bitPerSample = 0;if(TextUtils.isEmpty(path)){return null;}File file = new File(path);if(!file.exists()){return null;}InputStream  wavInputStrem = new FileInputStream(file);/*wav头部总共占44个字节*/ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE);buffer.order(ByteOrder.LITTLE_ENDIAN); //格式 采样率 采样大小 声道数都是小端存储wavInputStrem.read(buffer.array(), buffer.arrayOffset(), buffer.capacity());buffer.rewind();buffer.position(AUDIO_FORMAT_POSITION);int format = buffer.getShort();Log.e("WavPlayer", "format = " + format);/*pcm播放*/if(format != 1){Log.e("WavPlayer", "format is not pcm");return null;}buffer.rewind();buffer.position(AUDIO_NUM_CHANNEL_POSITION);int channel = buffer.getShort();Log.e("WavPlayer", "channel="+channel);if(channel == 2){info.channelMask = AudioFormat.CHANNEL_OUT_STEREO;}buffer.rewind();buffer.position(AUDIO_SAMPLE_RATE_POSITION);info.sampleRate = buffer.getInt();Log.e("WavPlayer", "sampleRate="+info.sampleRate);buffer.rewind();buffer.position(AUDIO_BIT_PERSAMPLE_POSITION);bitPerSample = buffer.getShort();Log.e("WavPlayer", "bitPerSample="+bitPerSample);if(bitPerSample == 16){info.audioFormatEncodeing = AudioFormat.ENCODING_PCM_16BIT;}else if(bitPerSample == 8){info.audioFormatEncodeing = AudioFormat.ENCODING_PCM_8BIT;}else{info.audioFormatEncodeing = AudioFormat.ENCODING_PCM_FLOAT;}wavInputStrem.close();}catch (Exception e){e.printStackTrace();}return info;}@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)private void init(WavData data) {executorService = Executors.newCachedThreadPool();AudioFormat.Builder builder = new AudioFormat.Builder();builder.setChannelMask(data.channelMask).setEncoding(data.audioFormatEncodeing).setSampleRate(data.sampleRate);AudioFormat audioFormat = builder.build();buffersize = AudioTrack.getMinBufferSize(data.sampleRate,data.channelMask,data.audioFormatEncodeing);Log.e("yuanAudioTrack", "init buffersize=" + buffersize);AudioAttributes audioAttributes = (new AudioAttributes.Builder()).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();mAudioTrack = new AudioTrack(audioAttributes,audioFormat,buffersize,AudioTrack.MODE_STREAM,AudioManager.AUDIO_SESSION_ID_GENERATE);}/*** 播放线程*/Runnable recordRunnable = new Runnable() {@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overridepublic void run() {try {//设置线程的优先级android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);byte[] tempBuffer = new byte[buffersize];int readCount = 0;while (inputStream.available() > 0) {readCount= inputStream.read(tempBuffer);if (readCount == AudioTrack.ERROR_INVALID_OPERATION || readCount == AudioTrack.ERROR_BAD_VALUE) {continue;}if (readCount != 0 && readCount != -1) {//一边播放一边写入语音数据//判断AudioTrack未初始化,停止播放的时候释放了,状态就为STATE_UNINITIALIZEDif(mAudioTrack.getState() == mAudioTrack.STATE_UNINITIALIZED){return;}mAudioTrack.play();mAudioTrack.write(tempBuffer, 0, readCount);}}stopPlay();//播放完就停止播放} catch (Exception e) {e.printStackTrace();}}};private void setPath(String path) throws Exception {File file = new File(path);inputStream = new DataInputStream(new FileInputStream(file));inputStream.skipBytes(HEADER_SIZE); //跳过WAV头部44个字节}public void stopPlay() {try {if (mAudioTrack != null) {if (mAudioTrack.getState() == AudioRecord.STATE_INITIALIZED) {//初始化成功mAudioTrack.stop();//停止播放}if (mAudioTrack != null) {mAudioTrack.release();//释放audioTrack资源}mAudioTrack = null;}if (inputStream != null) {inputStream.close();//关闭数据输入流}} catch (Exception e) {e.printStackTrace();}}public void startPlay(String path) {try {WavData wavData = getInfo(path);if(wavData == null){return;}init(wavData);setPath(path);executorService.execute(recordRunnable);} catch (Exception e) {e.printStackTrace();}}
}

gitee地址:https://gitee.com/creat151/android-media.git

AudioTrack 播放wav音频文件相关推荐

  1. Android使用AudioTrack播放WAV音频文件

    目录 1.wav文件格式 2.wav文件解析 3.wav文件播放 QA: 开始播放wav的时候使用了系统的播放器mediaplayer进行播放,但是无奈mediaplayer支持的实在不好. 好些年前 ...

  2. 实现在线播放Wav音频文件,支持IE和Google

    最近在弄一个在线播放Wav音频文件的功能,发现audio只支持在google浏览器下才能访问,ie是不支持的,但是ie支持embed标签的播放. getWebIE:function(){var use ...

  3. Java 采集声音_通过java采集PC麦克风音频及播放wav音频文件

    AudioFormat对象 sampleRate 采样率 每秒音频采样数量 sampleSizeInBits 采样位数 每个采样的位数 channels 声道 1: Mono 单声道,2:Stereo ...

  4. Linux下使用C++播放wav音频文件

    Linux下使用C++播放wav音频文件 安装openal第三方库 上代码 安装openal第三方库 unbuntu下安装命令:sudo apt-get install libopenal-dev 安 ...

  5. windows播放wav音频文件

    摘要   遇到过很三次win10系统下调用sndPlaySound导致虚拟内存(分页缓冲池)泄露的情况,于是乎便尝试换个方式播放wav文件,使用zplay库进行播放,还是存在泄露.后来参照网上的教程调 ...

  6. Python 调用pyaudio库录制以及播放wav音频文件

    1.Pyaudio简介 PyAudio 是语音处理的 Python 库,提供了比较丰富的功能. 2.功能 python的Pyaud模块可以调用电脑的麦克风或音响进行录音,音频播放,生成wav文件等. ...

  7. python播放wav文件_python3 写一个WAV音频文件播放器的代码

    环境:ubuntu 16.04 python3.5 pycharm 包 : wave pyaudio sys 上代码:AudioPlayer.py # coding:utf-8 # author:ki ...

  8. 音频制作与转换—WAV音频文件

    音频制作与转换-WAV音频文件 在音视频制作或转换中,常需要面临如下选择: 是否选择WAV这种音频文件格式:选择何种编码格式:如何设置采样频率(Hz.kHz).采样精度(bit).码率(kBps.比特 ...

  9. android 字节转wav,android开发:把一个byte数组转换成wav音频文件,并且播放

    ============问题描述============ 如题,byte数组转换成wav音频文件,并且播放,下面代码能生成data/data/com.example.playwav/cache/tem ...

最新文章

  1. C/S和B/S的区别
  2. 厉害了!SpringBoot是如何动起来的!
  3. python使用ElementTree解析XML文件
  4. 价值199的wp移植Emlog主题模板PandaPRO
  5. Android中URI的格式
  6. mgr未同步 mysql_MySQL MGR如何修复数据不一致的节点
  7. python之集合操作 - |
  8. 习惯性的对自己没信心,其实没想到自己已经变强大了。
  9. 计算机二级关系模式知识点,2013年计算机二级VFP关系模式知识点详解
  10. Redis核心知识点总结(一万五千字,请耐心读完)
  11. roseha linux,ROSEHA双机软件图解安装配置linux.docx
  12. 软件测试答疑:抽奖按钮怎么测试?
  13. 原来找展会会刊(参展商名录)这么简单
  14. Linux 脚本修改ps1,Linux使环境变量PS1的修改永久生效——修改配置文件/etc/profile...
  15. PS 2019 Mac版 自学入门系列(六)——裁剪和拉直图像
  16. Error: Delta RPMs disabled because /usr/bin/applyd
  17. 实现英文的大小写转换
  18. html5图片自动滑动,超简单的图片左右切换滑动
  19. unity的切屏显示顺序
  20. 第14周C++兄弟营团队学习情况记录表

热门文章

  1. jacob简单使用CAD与Excel
  2. 如何将手机wifi网络通过USB共享给电脑使用
  3. Revit翻模软件:管件二维注释比例改变和【管道翻模】
  4. 矩阵的初等变换和等价
  5. WIN7无法保存打印机设置错误0x000006d9处理办法(转载)
  6. linux 基础命令测试题,grep命令基础练习题
  7. emu8086 第一个程序
  8. android 版本分布 友盟,友盟推送
  9. pta c语言 选择法排序
  10. [kubernetes]-k8s安装alertmanager和prometheus-webhook-dingtalk