我目前正在开发一个 Android 应用程序,必须将麦克风输入录制为PCM流。
每当我录制某些内容时,我会遇到一些奇怪的口吃,我无法找到解决方法。
这是我的代码:
在我的MainActivity中,我有一个 ASyncTask 用于麦克风输入:
ArrayList<byte[]> mBufferList;
@Override
protected String doInBackground(String... params) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
mMicrophone = new Microphone();
mMicrophone.init();
byte[] buffer;
while (mRecord) {
try {
mMicrophone.record();
buffer = mMicrophone.getBuffer();
mBufferList.add(buffer);
}
catch
{
}
}
}
在我的麦克风类中,我初始化了AudioRecorder:
public void init() {
Log.d("DEBUG", "Microphone: Recording started");
mBufferSize = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
mRecorder = new AudioRecord(AudioSource.MIC, 44100,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, mBufferSize);
mRecorder.startRecording();
mBuffer = new short[mBufferSize];
}
记录方法:
public void record() throws IOException {
mRecorder.read(mBuffer, 0, mBufferSize);
}
短[]到字节[]:
public byte[] shortToBytes(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
检索缓冲区的方法:
public byte[] getBuffer() {
byte[] buffer = shortToBytes(mBuffer);
return buffer;
}
我上传了一个wav文件,演示了口吃效果。我说'一个人': Wav-File
我已经尝试更改了样本,缓冲等等,但没有用。
非常感谢任何帮助!如果有人能帮助我的话会很棒!
请注意:由于我在Android设备上对其进行了测试,甚至将原始数据发送到了pcm流,因此重播pcm流的方式错误不会导致 服务器将文件转换为wav那里。
答案 0 :(得分:4)
经过几个小时的拼命寻找解决方案后,我终于找到了错误。
我偶然在Microphone类中创建了我的短缓冲区,如下所示:
mBuffer = new short[mBufferSize];
缓冲区大小以字节为单位,所以我当然必须使用 mBuffersize / 2
mBuffer = new short[mBufferSize/2];
如果有人对代码感兴趣和/或有类似的问题,我会在线保留我的问题。