import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import java.io.IOException;
import java.io.RandomAccessFile;
public class SWKFileRecorder {
// 錄音狀態(tài)
private boolean isRecording = true;
public void startRecording(String outFilePath){
// 耗時(shí)操作要開線程
new Thread(){
@Override
public void run() {
// 音源
int audioSource = MediaRecorder.AudioSource.MIC;
// 采樣率
int sampleRate = 16000;
// 聲道數(shù)
int channelConfig = AudioFormat.CHANNEL_IN_MONO;//單聲道
// 采樣位數(shù)
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 獲取最小緩存區(qū)大小
int minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
// 創(chuàng)建錄音對(duì)象
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioFormat, minBufferSize);
try {
// 創(chuàng)建隨機(jī)讀寫流
RandomAccessFile raf = new RandomAccessFile(outFilePath, "rw");
// 留出文件頭的位置
raf.seek(44);
byte[] buffer = new byte[minBufferSize];
// 錄音中
audioRecord.startRecording();
isRecording = true;
while (isRecording) {
int readSize = audioRecord.read(buffer, 0, minBufferSize);
raf.write(buffer,0,readSize);
}
// 錄音停止
audioRecord.stop();
audioRecord.release();
// 寫文件頭
WriteWaveFileHeader(raf, raf.length(),sampleRate,1,sampleRate*16*1/8);
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 為 wav 文件添加文件頭,前提是在頭部預(yù)留了 44字節(jié)空間
*
* @param raf
* 隨機(jī)讀寫流
* @param fileLength
* 文件總長(zhǎng)
* @param sampleRate
* 采樣率
* @param channels
* 聲道數(shù)量
* @param byteRate
* 碼率 = 采樣率 * 采樣位數(shù) * 聲道數(shù) / 8
* @throws IOException
*/
private void WriteWaveFileHeader(RandomAccessFile raf, long fileLength, long sampleRate, int channels, long byteRate) throws IOException {
long totalDataLen = fileLength + 36;
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[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 ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (sampleRate & 0xff);
header[25] = (byte) ((sampleRate >> 8) & 0xff);
header[26] = (byte) ((sampleRate >> 16) & 0xff);
header[27] = (byte) ((sampleRate >> 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 align
header[33] = 0;
header[34] = 16; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (fileLength & 0xff);
header[41] = (byte) ((fileLength >> 8) & 0xff);
header[42] = (byte) ((fileLength >> 16) & 0xff);
header[43] = (byte) ((fileLength >> 24) & 0xff);
raf.seek(0);
raf.write(header, 0, 44);
}
public void stopRecording() {
// 停止錄音
isRecording = false;
}
}
安卓錄制wav文件
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 需求 錄制音頻文件,需要支持暫停,再錄制。暫停狀態(tài)下可播放錄音,播放完畢后能繼續(xù)錄制! 最初的我 由于之前做過(guò)錄音...
- 錄制原理:1,RecorderManager中通過(guò)AudioSession進(jìn)行PCM音頻錄制,錄制格式為WAV格式...
- #include "alsa/asoundlib.h" /* this buffer holds the digi...
- PCM PCM(Pulse Code Modulation),脈沖編碼調(diào)制。人耳聽到的是模擬信號(hào),PCM是把聲音從...