android录音程序之wav文件头

来源:互联网 发布:招财金软件 编辑:程序博客网 时间:2024/05/21 09:15

网上搜索到的录音代码里都有一段处理wav文件头的代码:

/** * 这里提供一个头信息。插入这些信息就可以得到可以播放的文件。 * 为我为啥插入这44个字节,这个还真没深入研究,不过你随便打开一个wav * 音频的文件,可以发现前面的头文件可以说基本一样哦。每种格式的文件都有 * 自己特有的头文件。 */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'; // RIFF/WAVE headerheader[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'; // 'fmt ' chunkheader[13] = 'm';header[14] = 't';header[15] = ' ';header[16] = 16; // 4 bytes: size of 'fmt ' chunkheader[17] = 0;header[18] = 0;header[19] = 0;header[20] = 1; // format = 1header[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); // block alignheader[33] = 0;header[34] = 16; // bits per sampleheader[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);}

反编译出来原音录音机,可以看到类似的处理:

private static byte[] intToByteArray(int paramInt)  {    byte[] arrayOfByte = new byte[4];    arrayOfByte[0] = (byte)(paramInt & 0xFF);    arrayOfByte[1] = (byte)(0xFF & paramInt >> 8);    arrayOfByte[2] = (byte)(0xFF & paramInt >> 16);    arrayOfByte[3] = (byte)(0xFF & paramInt >> 24);    return arrayOfByte;  }  private static byte[] shortToByteArray(short paramShort)  {    byte[] arrayOfByte = new byte[2];    arrayOfByte[0] = (byte)(paramShort & 0xFF);    arrayOfByte[1] = (byte)(0xFF & paramShort >>> 8);    return arrayOfByte;  }  private void writerHeader(RandomAccessFile paramRandomAccessFile, int paramInt)    throws IOException  {    if (this.waveFile == null)      return;    paramRandomAccessFile.writeBytes("RIFF");    paramRandomAccessFile.write(intToByteArray(paramInt + 24), 0, 4);    paramRandomAccessFile.writeBytes("WAVE");    paramRandomAccessFile.writeBytes("fmt ");    paramRandomAccessFile.write(intToByteArray(16), 0, 4);    paramRandomAccessFile.write(shortToByteArray(1), 0, 2);    paramRandomAccessFile.write(shortToByteArray((short)this.channels), 0, 2);    paramRandomAccessFile.write(intToByteArray(this.sampleRate), 0, 4);    paramRandomAccessFile.write(intToByteArray(this.byteRate * this.sampleRate * this.channels), 0, 4);    paramRandomAccessFile.write(shortToByteArray((short)(this.byteRate * this.channels)), 0, 2);    paramRandomAccessFile.write(shortToByteArray((short)(8 * this.byteRate)), 0, 2);    paramRandomAccessFile.writeBytes("data");    paramRandomAccessFile.write(intToByteArray(paramInt), 0, 4);  }

可以看到,其中有几个参数是跟byteRate和channels有关的,如果前面的几个参数调整,会影响这两个参数,而网上的代码是写死的。

另外常用的几个音质的参数:

    WAVE_STEREO_44K_16B = new AudioSetting(44100, 12, 12, 2, 2, 2, "CD 音质", FileType.Wav);    WAVE_STEREO_22K_16B = new AudioSetting(22050, 12, 12, 2, 2, 2, "Half CD 音质", FileType.Wav);    WAVE_STEREO_16K_8B = new AudioSetting(16000, 12, 12, 3, 2, 1, "VoIP 音质", FileType.Wav);    WAVE_STEREO_8K_8B = new AudioSetting(8000, 12, 12, 3, 2, 1, "电话音质", FileType.Wav);    WAVE_MONO_44K_16B = new AudioSetting(44100, 16, 4, 2, 1, 2, "CD 音质", FileType.Wav);    WAVE_MONO_16K_8B = new AudioSetting(16000, 16, 4, 3, 1, 1, "VoIP 音质", FileType.Wav);    MP3_STEREO_44K_16B_128 = new MP3AudioSetting(44100, 12, 12, 2, 2, 2, "CD 音质", FileType.MP3, 128);    MP3_MONO_44K_16B_128 = new MP3AudioSetting(44100, 16, 4, 2, 1, 2, "CD 音质", FileType.MP3, 128);    MP3_STEREO_44K_16B_160 = new MP3AudioSetting(44100, 12, 12, 2, 2, 2, "CD 音质", FileType.MP3, 160);    MP3_MONO_44K_16B_160 = new MP3AudioSetting(44100, 16, 4, 2, 1, 2, "CD 音质", FileType.MP3, 160);    MP3_STEREO_44K_16B_192 = new MP3AudioSetting(44100, 12, 12, 2, 2, 2, "CD 音质", FileType.MP3, 192);    MP3_MONO_44K_16B_192 = new MP3AudioSetting(44100, 16, 4, 2, 1, 2, "CD 音质", FileType.MP3, 192);

另外发现获取到最低缓冲区大小后,创建Record时可以使用最低缓冲区大小的多倍作为参数。

this.audioRecord = new AudioRecord(1, this.setting.sampleRate, this.setting.inChannelConfiguration, this.setting.audioEncoding,  2 * this.setting.inBufferSize);this.audioRecord = new AudioRecord(1, this.setting.sampleRate, this.setting.inChannelConfiguration, this.setting.audioEncoding, 10 * this.setting.inBufferSize);   

创建后,可以使用下面的代码判断Record的状态。

if (this.audioRecord.getState() == 0)    {      this.audioRecord = null;      throw new AudioDeviceException(AudioDeviceException.DEVICE_TYPE_RECORD);    }




原创粉丝点击