PCM音訊資料檔案轉wav檔案
阿新 • • 發佈:2021-06-23
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; } }