关于android 使用audiorecord 录制pcm文件 音频速度变快的问题求教

8 篇文章 0 订阅
5 篇文章 0 订阅

录制音频后 播放速度变快

录制音频文件

我使用aduiorecord录制pcm文件 录制代码如下

创建实例

mAudioRecorder = new AudioRecord(
						mRecorderBuilder.mAudioSource,
						sample_rate,
						channel_config, 
						format,
						mRecorderBuilder.bufferSize);
						

其中参数含义


private int mAudioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;//自动降噪,也尝试过 MIC
		private int mSampleRate = SAMPLE_RATE_44K_HZ;//44100
		private int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;//单声道
		private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;//每次采样位数
		mRecorderBuilder.bufferSize//缓冲区大小,其值大于 用AudioRecord.getMinBufferSize(sample_rate, channel_config, format) 获取的最小值

录音


//mPcmBuffer.size就是上面的mRecorderBuilder.bufferSize 大小
//private short[] mPcmBuffer
	mAudioRecorder.read(mPcmBuffer, 0, mPcmBuffer.length);

存储

我是通过随机存储文件对象,进行数据的存储.
由于需要存储为wav格式的文件,因此需要写头文件.
头文件中需要计算 当前录音的格式 数据
第一次写,网上找的格式写的1

RandomAccessFile rand = new RandomAccessFile(saveFile, "rw");

RandomAccessFile rand = randomAccessFile;


		long totalDataLen = totalAudioLen + 36;
		rand.seek(0);

		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) (nChannels & 0xff);
		header[23] = (byte) ((nChannels >> 8) & 0xff);

		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);

		int b = weikuan * nChannels / 8;//每次采样的大小
		header[32] = (byte) (b & 0xff); // block align
		header[33] = (byte) ((b >> 8) & 0xff);
		header[34] = (byte) (weikuan & 0xff);
		header[35] = (byte) ((weikuan >> 8) & 0xff);
		header[36] = 'd';//data
		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);

		rand.write(header, 0, 44);

写完之后将写入pcm数据流 我这里分装了一个对象,单独开了一个写文件线程.
通过handler 开启工作线程(之前的录音也是一个单独的线程具体看demo)

saveFileThread = new SaveFileThread();
		saveFileThread.start();
		saveHandler = new SaveFileThread.SaveHandler(saveFileThread);


				if (msg.what == SAVEING) {
					saving = true;
					while (saveFileThread.doWork() > 0) ;
//					Log.e(SaveFileThreadTAG, "收到 msg");

					saving = false;
				} else if (msg.what == STOP) {
					saveFileThread.finish();
					removeCallbacksAndMessages(null);
					getLooper().quit();

				}

			SaveTask remove = saveDatas.remove(0);
			int mSize = remove.mSize;
			saveFile.saveByet(remove.saveData, 0, mSize);

至此wav文件录制完毕

遇见的问题

录出来的wav文件,播放时 语速非常快, 感觉是快进了两倍.
找了很多原因都找不到,网上搜了几天,无果.只有一篇帖子很像2

但是该帖子并没有解决我的问题

特此发帖,一方面是记录一下自己的demo
二来,希望哪位大神可以帮我看一下,我的demo到底出了说明问题

ps :demo中还实现了 lame库 将 pcm格式转换为mp3 格式的文件.使用 pcm格式文件转换可以正常使用

我的demo地址 https://github.com/MartinLi89/myrecorder.git


  1. wav头文件说明(https://blog.csdn.net/hsy12342611/article/details/80075836) ↩︎

  2. 帖子https://blog.csdn.net/marller/article/details/52882387 ↩︎

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
使用AudioRecord录制音频并转换成wav格式,需要进行以下步骤: 1. 设置录音参数:采样率、音频通道、编码格式等 2. 创建一个AudioRecord对象 3. 开始录制音频,将音频数据写入到一个缓存区 4. 录制完成后,停止录音并释放AudioRecord对象 5. 将缓存区中的音频数据写入到一个wav文件中 下面是一个简单的示例代码,演示如何使用AudioRecord录制音频并将其转换成wav格式: ``` // 设置录音参数 int sampleRateInHz = 44100; int channelConfig = AudioFormat.CHANNEL_IN_MONO; int audioFormat = AudioFormat.ENCODING_PCM_16BIT; int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 创建AudioRecord对象 AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes); // 开始录音 audioRecord.startRecording(); // 定义缓存区 byte[] buffer = new byte[bufferSizeInBytes]; // 定义输出文件 String outputFileName = "output.wav"; File outputFile = new File(Environment.getExternalStorageDirectory(), outputFileName); // 定义输出流 FileOutputStream outputStream = new FileOutputStream(outputFile); // 写入wav文件头 WaveHeader waveHeader = new WaveHeader(sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes); waveHeader.write(outputStream); // 写入音频数据 int readSize; while ((readSize = audioRecord.read(buffer, 0, bufferSizeInBytes)) != AudioRecord.ERROR_INVALID_OPERATION) { outputStream.write(buffer, 0, readSize); } // 停止录音并释放资源 audioRecord.stop(); audioRecord.release(); // 关闭输出流 outputStream.close(); ``` 在上述代码中,我们使用了一个自定义的WaveHeader类,用于生成wav文件头信息。该类的实现可以参考下面的示例代码: ``` public class WaveHeader { private int sampleRate; private int channelCount; private int audioFormat; private int audioDataLength; public WaveHeader(int sampleRate, int channelCount, int audioFormat, int audioDataLength) { this.sampleRate = sampleRate; this.channelCount = channelCount; this.audioFormat = audioFormat; this.audioDataLength = audioDataLength; } public void write(OutputStream outputStream) throws IOException { outputStream.write("RIFF".getBytes()); outputStream.write(intToByteArray(36 + audioDataLength), 0, 4); outputStream.write("WAVE".getBytes()); outputStream.write("fmt ".getBytes()); outputStream.write(intToByteArray(16), 0, 4); outputStream.write(shortToByteArray((short) 1), 0, 2); outputStream.write(shortToByteArray((short) channelCount), 0, 2); outputStream.write(intToByteArray(sampleRate), 0, 4); outputStream.write(intToByteArray(sampleRate * channelCount * audioFormat / 8), 0, 4); outputStream.write(shortToByteArray((short) (channelCount * audioFormat / 8)), 0, 2); outputStream.write(shortToByteArray((short) audioFormat), 0, 2); outputStream.write("data".getBytes()); outputStream.write(intToByteArray(audioDataLength), 0, 4); } private byte[] intToByteArray(int value) { byte[] byteArray = new byte[4]; byteArray[0] = (byte) (value & 0xff); byteArray[1] = (byte) ((value >> 8) & 0xff); byteArray[2] = (byte) ((value >> 16) & 0xff); byteArray[3] = (byte) ((value >> 24) & 0xff); return byteArray; } private byte[] shortToByteArray(short value) { byte[] byteArray = new byte[2]; byteArray[0] = (byte) (value & 0xff); byteArray[1] = (byte) ((value >> 8) & 0xff); return byteArray; } } ``` 通过以上代码,我们可以实现将AudioRecord录制音频转换成wav格式并保存到文件中。需要注意的是,由于Android 6.0及以上版本需要动态获取录音权限,因此在使用前需要先请求录音权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值