wave混音的实现(1)

阅读更多
先看关于wav文件的头信息
wave混音的实现(1)_第1张图片
下面是封装好的一个辅助类。用于生成头部信息。
package example.audiotest;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
 * 
 * @author cninjazh
 * WavHeader辅助类。用于生成头部信息。
 * WAV标准,头部应该是44字节
 */
public class WaveHeader {
	public final char fileID[] = { 'R', 'I', 'F', 'F' };
	public int fileLength;
	public char wavTag[] = { 'W', 'A', 'V', 'E' };
	public char fmtHdrID[] = { 'f', 'm', 't', ' ' };
	public int fmtHdrLeth;
	public short formatTag;
	public short channels;
	public int samplesPerSec;
	public int avgBytesPerSec;
	public short blockAlign;
	public short bitsPerSample;
	public char dataHdrID[] = { 'd', 'a', 't', 'a' };
	public int dataHdrLeth;
	/*
	 * pre-define wave header for 256kbps, 16bit, 16kHz, 1(mono), pcm
	 * 填入参数,比特率等等。这里用的是16位单声道 16000Hz
	 * fileLength = 内容的大小(dataSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
	 * avgBytesPerSec = 8bit/16bit、11kHz/16kHz的WAV流进行传输(最大流量为16*16=256kbps=32KB/s)
	 */
	public WaveHeader(int dataSize) {
		fileLength = dataSize + (44 - 8);
		fmtHdrLeth = 16;
		bitsPerSample = 16;
		channels = 1;
		formatTag = 0x0001;
		samplesPerSec = 16000;
		blockAlign = (short) (channels * bitsPerSample / 8);
		avgBytesPerSec = blockAlign * samplesPerSec;
		dataHdrLeth = dataSize;
	}
	
	public WaveHeader(int dataSize, short bitsPerSample, int samplesPerSec) {
		fileLength = dataSize + (44 - 8);
		fmtHdrLeth = 16;
		this.bitsPerSample = bitsPerSample;
		channels = 1;
		formatTag = 0x0001;
		this.samplesPerSec = samplesPerSec;
		blockAlign = (short) (channels * bitsPerSample / 8);
		avgBytesPerSec = blockAlign * samplesPerSec;
		dataHdrLeth = dataSize;
	}
	
	public byte[] getHeader() throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		/*
		 * ①RIFF WAVE Chunk
  			==================================
 			 | |所占字节数| 具体内容 |
  			==================================
 			 | ID | 4 Bytes | 'RIFF' |
 			----------------------------------
 			 | Size | 4 Bytes | |
  			----------------------------------
 			 | Type | 4 Bytes | 'WAVE' |
 			----------------------------------
		 */
		WriteChar(bos, fileID);//以RIFF作为标识
		WriteInt(bos, fileLength);//size,该size的大小是整个WAVE文件大小减去8个字节
		WriteChar(bos, wavTag);//Type字段,为"WAVE"表示是Wav文件
		/*
		 * ②Format Chunk
  			====================================================================
  			| | 字节数 | 具体内容 |
  			====================================================================
 			| ID | 4 Bytes | 'fmt ' |
  			--------------------------------------------------------------------
  			| Size | 4 Bytes | 数值为16或18,18则最后又附加信息 |
 			 -------------------------------------------------------------------- ----
 		 	| FormatTag | 2 Bytes | 编码方式,一般为0x0001 | |
  			-------------------------------------------------------------------- |
  			| Channels | 2 Bytes | 声道数目,1--单声道;2--双声道 | |
  			-------------------------------------------------------------------- |
  			| SamplesPerSec | 4 Bytes | 采样频率 | |
  			-------------------------------------------------------------------- |
  			| AvgBytesPerSec| 4 Bytes | 每秒所需字节数 | |===> WAVE_FORMAT
  			-------------------------------------------------------------------- |
  			| BlockAlign | 2 Bytes | 数据块对齐单位(每个采样需要的字节数) | |
  			-------------------------------------------------------------------- |
  			| BitsPerSample | 2 Bytes | 每个采样需要的bit数 | |
  			-------------------------------------------------------------------- |
  			| | 2 Bytes | 附加信息(可选,通过Size来判断有无) | |
  			-------------------------------------------------------------------- ----
		 */
		WriteChar(bos, fmtHdrID);//以"fmt "作为标识
		WriteInt(bos, fmtHdrLeth);//一般长度为16个字节,如果是18个字节则有附加信息,写在最后两个字节上
		WriteShort(bos, formatTag);
		WriteShort(bos, channels);
		WriteInt(bos, samplesPerSec);
		WriteInt(bos, avgBytesPerSec);
		WriteShort(bos, blockAlign);
		WriteShort(bos, bitsPerSample);
		
		WriteChar(bos, dataHdrID);
		WriteInt(bos, dataHdrLeth);
		bos.flush();
		byte[] r = bos.toByteArray();
		bos.close();
		return r;
	}

	private void WriteShort(ByteArrayOutputStream bos, int s)
			throws IOException {
		byte[] mybyte = new byte[2];
		mybyte[1] = (byte) ((s << 16) >> 24);
		mybyte[0] = (byte) ((s << 24) >> 24);
		bos.write(mybyte);
	}

	private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException {
		byte[] buf = new byte[4];
		buf[3] = (byte) (n >> 24);
		buf[2] = (byte) ((n << 8) >> 24);
		buf[1] = (byte) ((n << 16) >> 24);
		buf[0] = (byte) ((n << 24) >> 24);
		bos.write(buf);
	}

	private void WriteChar(ByteArrayOutputStream bos, char[] id) {
		for (int i = 0; i < id.length; i++) {
			char c = id[i];
			bos.write(c);
		}
	}
}

  • wave混音的实现(1)_第2张图片
  • 大小: 76 KB
  • 查看图片附件

你可能感兴趣的:(F#,C,C++,C#)