andriod拼凑wav声音文件
来源:互联网 发布:乌克兰 俄罗斯 知乎 编辑:程序博客网 时间:2024/06/05 00:39
上一篇文章中介绍了,在windows的目录下,如何拼凑两个声音文件,下面来介绍一下在andriod中如何拼凑声音文件。 WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,该格式也支持MSADPCM,CCITT A LAW等多种压缩运算法,支持多种音频数字,取样频率和声道,标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在声音文件质量和CD相差无几! WAV打开工具是WINDOWS的媒体播放器。 通常使用三个参数来表示声音,量化位数,取样频率和采样点振幅。量化位数分为8位,16位,24位三种,声道有单声道和立体声之分,单声道振幅数据为n*1矩阵点,立体声为n*2矩阵点,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种,不过尽管音质出色,但在压缩后的文件体积过大!相对其他音频格式而言是一个缺点,其文件大小的计算方式为:WAV格式文件所占容量(B) = (取样频率 X量化位数X 声道) X 时间 / 8 (字节= 8bit) 每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化。 由于这里采集的音频相关参数一致,做我们去其中一段的头部作为拼接后的音频的头部。但是也不是这样就可以了。从上面WAV的格式中可以看出,头部中两个位置的数据需要修改。1、riff chunk中的size值;2、data chunk的size值。因此可以先将其他数据的data chunk部分的数据追加到结果文件中,最后写入这两个地方的值。
public class WavMergeUtil { //inputs 为包含file对象的list //output 为输出的目录文件。 public static void mergeWav(List<File> inputs, File output) throws IOException { if (inputs.size() < 1) { return; } FileInputStream fis = new FileInputStream(inputs.get(0)); FileOutputStream fos = new FileOutputStream(output); byte[] buffer = new byte[2048]; int total = 0; int count; while ((count = fis.read(buffer)) > -1) { fos.write(buffer, 0, count); total += count; } fis.close(); for (int i = 1; i < inputs.size(); i++) { File file = inputs.get(i); Header header = resolveHeader(file); FileInputStream dataInputStream = header.dataInputStream; while ((count = dataInputStream.read(buffer)) > -1) { fos.write(buffer, 0, count); total += count; } dataInputStream.close(); } fos.flush(); fos.close(); Header outputHeader = resolveHeader(output); outputHeader.dataInputStream.close(); RandomAccessFile res = new RandomAccessFile(output, "rw"); res.seek(4); byte[] fileLen = intToByteArray(total + outputHeader.dataOffset - 8); res.write(fileLen, 0, 4); res.seek(outputHeader.dataSizeOffset); byte[] dataLen = intToByteArray(total); res.write(dataLen, 0, 4); res.close(); } /** * 解析头部,并获得文件指针指向数据开始位置的InputStreram,记得使用后需要关闭 */ private static Header resolveHeader(File wavFile) throws IOException { FileInputStream fis = new FileInputStream(wavFile); byte[] byte4 = new byte[4]; byte[] buffer = new byte[2048]; int readCount = 0; Header header = new Header(); fis.read(byte4);//RIFF fis.read(byte4); readCount += 8; header.fileSizeOffset = 4; header.fileSize = byteArrayToInt(byte4); fis.read(byte4);//WAVE fis.read(byte4);//fmt fis.read(byte4); readCount += 12; int fmtLen = byteArrayToInt(byte4); fis.read(buffer, 0, fmtLen); readCount += fmtLen; fis.read(byte4);//data or fact readCount += 4; if (isFmt(byte4, 0)) {//包含fmt段 fis.read(byte4); int factLen = byteArrayToInt(byte4); fis.read(buffer, 0, factLen); fis.read(byte4);//data readCount += 8 + factLen; } fis.read(byte4);// data size int dataLen = byteArrayToInt(byte4); header.dataSize = dataLen; header.dataSizeOffset = readCount; readCount += 4; header.dataOffset = readCount; header.dataInputStream = fis; return header; } private static boolean isRiff(byte[] bytes, int start) { if (bytes[start + 0] == 'R' && bytes[start + 1] == 'I' && bytes[start + 2] == 'F' && bytes[start + 3] == 'F') { return true; } else { return false; } } private static boolean isFmt(byte[] bytes, int start) { if (bytes[start + 0] == 'f' && bytes[start + 1] == 'm' && bytes[start + 2] == 't' && bytes[start + 3] == ' ') { return true; } else { return false; } } private static boolean isData(byte[] bytes, int start) { if (bytes[start + 0] == 'd' && bytes[start + 1] == 'a' && bytes[start + 2] == 't' && bytes[start + 3] == 'a') { return true; } else { return false; } } /** * 将int转化为byte[] */ private static byte[] intToByteArray(int data) { return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(data).array(); } /** * 将short转化为byte[] */ private static byte[] shortToByteArray(short data) { return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(data).array(); } /** * 将byte[]转化为short */ private static short byteArrayToShort(byte[] b) { return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getShort(); } /** * 将byte[]转化为int */ private static int byteArrayToInt(byte[] b) { return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt(); } /** * 头部部分信息 */ static class Header { public int fileSize; public int fileSizeOffset; public int dataSize; public int dataSizeOffset; public int dataOffset; public FileInputStream dataInputStream; }}
下面介绍第二种拼凑的方法,见代码:
private static final byte RECORDER_BPP = 16;private static final long RECORDER_SAMPLERATE = 44100;private void CombineWaveFile(String file1, String file2) { FileInputStream in1 = null, in2 = null; FileOutputStream out = null; long totalAudioLen = 0; long totalDataLen = totalAudioLen + 36; long longSampleRate = RECORDER_SAMPLERATE; int channels = 2; long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels / 8; byte[] data = new byte[bufferSize]; try { in1 = new FileInputStream(file1); in2 = new FileInputStream(file2); out = new FileOutputStream(getFilename3()); totalAudioLen = in1.getChannel().size() + in2.getChannel().size(); totalDataLen = totalAudioLen + 36; WriteWaveFileHeader(out, totalAudioLen, totalDataLen, longSampleRate, channels, byteRate); while (in1.read(data) != -1) { out.write(data); } while (in2.read(data) != -1) { out.write(data); } out.close(); in1.close(); in2.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen,long totalDataLen, long longSampleRate, int channels, long byteRate)throws IOException { byte[] header = new byte[44]; header[0] = 'R'; header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte)(totalDataLen & 0xff); header[5] = (byte)((totalDataLen >> 8) & 0xff); header[6] = (byte)((totalDataLen >> 16) & 0xff); header[7] = (byte)((totalDataLen >> 24) & 0xff); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte)(longSampleRate & 0xff); header[25] = (byte)((longSampleRate >> 8) & 0xff); header[26] = (byte)((longSampleRate >> 16) & 0xff); header[27] = (byte)((longSampleRate >> 24) & 0xff); header[28] = (byte)(byteRate & 0xff); header[29] = (byte)((byteRate >> 8) & 0xff); header[30] = (byte)((byteRate >> 16) & 0xff); header[31] = (byte)((byteRate >> 24) & 0xff); header[32] = (byte)(2 * 16 / 8); header[33] = 0; header[34] = RECORDER_BPP; header[35] = 0; header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte)(totalAudioLen & 0xff); header[41] = (byte)((totalAudioLen >> 8) & 0xff); header[42] = (byte)((totalAudioLen >> 16) & 0xff); header[43] = (byte)((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44);}
敲代码写文章真的挺不容易的,请各位兄弟姐妹们不要直接copy之后就搞成自己的,谢谢。
阅读全文
1 0
- andriod拼凑wav声音文件
- windows拼凑wav文件
- c++播放wav声音文件
- c++播放wav声音文件
- 1. 读取WAV声音文件
- QT播放.WAV声音文件
- HTML嵌入wav声音文件
- java 播放 wav 声音文件
- 使用DirectX播放wav声音文件
- VC6.0中播放WAV格式声音文件
- qt4.8+Phonon播放.wav声音文件
- windows播放wav声音文件--java播放wav完整demo
- Java编程播放.wav或.au等声音文件
- WinCE系统播放wav声音文件的实现方法
- vb.net、vb播放声音 wince下播放声音文件(wav)
- BlackBerry 10:Qt中使用OpenAL播放wav声音文件
- .wav格式的声音文件怎么变成matlab 中的.mat文件
- 使用windows API播放声音文件(wav、mp3)等
- IPC之AIDL(3)系统为我们做了什么
- MyBatis对于Java对象里的枚举类型处理
- java 内存图
- PHP中使用cURL实现Get和Post请求的方法
- RT9293和boost电路分析
- andriod拼凑wav声音文件
- 字符串学习(4)
- Python抓取网页并保存为PDF
- Apache中限制和允许特定IP访问
- 支付宝支付签名、请求、解析demo
- 爬虫程序的简单介绍(Python)
- 通过java反射机制,获取对象的属性和值(包括所有继承的父类)
- jquery带右侧索引的通讯录
- CRM概念的产生与发展