PCM音频数据文件转wav文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCM音频数据文件转wav文件相关的知识,希望对你有一定的参考价值。

 1 package net.pengsn;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 
 6 public class WaveHeader {
 7 
 8     public final char fileID[] = {\'R\', \'I\', \'F\', \'F\'};
 9     public int fileLength;
10     public char wavTag[] = {\'W\', \'A\', \'V\', \'E\'};;
11     public char FmtHdrID[] = {\'f\', \'m\', \'t\', \' \'};
12     public int FmtHdrLeth;
13     public short FormatTag;
14     public short Channels;
15     public int SamplesPerSec;
16     public int AvgBytesPerSec;
17     public short BlockAlign;
18     public short BitsPerSample;
19     public char DataHdrID[] = {\'d\',\'a\',\'t\',\'a\'};
20     public int DataHdrLeth;
21 
22     public byte[] getHeader() throws IOException {
23         ByteArrayOutputStream bos = new ByteArrayOutputStream();
24         WriteChar(bos, fileID);
25         WriteInt(bos, fileLength);
26         WriteChar(bos, wavTag);
27         WriteChar(bos, FmtHdrID);
28         WriteInt(bos,FmtHdrLeth);
29         WriteShort(bos,FormatTag);
30         WriteShort(bos,Channels);
31         WriteInt(bos,SamplesPerSec);
32         WriteInt(bos,AvgBytesPerSec);
33         WriteShort(bos,BlockAlign);
34         WriteShort(bos,BitsPerSample);
35         WriteChar(bos,DataHdrID);
36         WriteInt(bos,DataHdrLeth);
37         bos.flush();
38         byte[] r = bos.toByteArray();
39         bos.close();
40         return r;
41     }
42 
43     private void WriteShort(ByteArrayOutputStream bos, int s) throws IOException {
44         byte[] mybyte = new byte[2];
45         mybyte[1] =(byte)( (s << 16) >> 24 );
46         mybyte[0] =(byte)( (s << 24) >> 24 );
47         bos.write(mybyte);
48     }
49 
50 
51     private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException {
52         byte[] buf = new byte[4];
53         buf[3] =(byte)( n >> 24 );
54         buf[2] =(byte)( (n << 8) >> 24 );
55         buf[1] =(byte)( (n << 16) >> 24 );
56         buf[0] =(byte)( (n << 24) >> 24 );
57         bos.write(buf);
58     }
59 
60     private void WriteChar(ByteArrayOutputStream bos, char[] id) {
61         for (int i=0; i<id.length; i++) {
62             char c = id[i];
63             bos.write(c);
64         }
65     }
66 }
package net.pengsn;

import java.io.*;
import com.alibaba.druid.util.StringUtils;

public class ShellUtils {
    
    public static void main(String[]args) {
        tranPcmToWavFile(new File("D://a.pcm"));
    }
    
    public static File tranPcmToWavFile(File pcmFile) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(pcmFile);
            String wavfilepath = pcmFile.getAbsolutePath().substring(0, pcmFile.getAbsolutePath().lastIndexOf(".")) + ".wav" ;


            File file = new File(wavfilepath);
            if (!file.exists()) {
                file.createNewFile();
            }
            fos = new FileOutputStream(wavfilepath);


            int PCMSize = 0;
            byte[] buf = new byte[1024 * 4];
            int size = fis.read(buf);

            while (size != -1) {
                PCMSize += size;
                size = fis.read(buf);
            }
            fis.close();

            //填入参数,比特率等等。这里用的是16位单声道 8000 hz

            WaveHeader header = new WaveHeader();
            //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
            header.fileLength = PCMSize + (44 - 8);
            header.FmtHdrLeth = 16;
            header.BitsPerSample = 16;
            header.Channels = 1;
            header.FormatTag = 0x0001;
            header.SamplesPerSec = 16000; // 注意采样频率
            header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
            header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
            header.DataHdrLeth = PCMSize;

            byte[] h = header.getHeader();

            assert h.length == 44; //WAV标准,头部应该是44字节
            //write header
            fos.write(h, 0, h.length);
            //write data stream
            fis = new FileInputStream(pcmFile);
            size = fis.read(buf);
            while (size != -1) {
                fos.write(buf, 0, size);
                size = fis.read(buf);
            }
            fis.close();
            fos.close();
            return new File(wavfilepath);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

 

以上是关于PCM音频数据文件转wav文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将wav音频文件格式为pcm转化为ima adpcm格式

wav格式和pcm格式怎么相互转换?

音频转码

音频数据文件格式(PCM,WAV,MIDI)简记

多媒体文件格式:PCM / WAV 格式

音频处理WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )