wave混音的实现(1)

先看关于wav文件的头信息
[img]http://dl.iteye.com/upload/attachment/312385/146446c8-133b-3234-b0b8-42f547322bd1.png[/img]
下面是封装好的一个辅助类。用于生成头部信息。
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);
}
}
}

你可能感兴趣的:(j2me)