Android:AudioRecord.read()返回垃圾
问题描述:
我一直在研究一个可以实时从麦克风播放音频的应用程序。 它设置了一个AudioRecorder,它没有任何错误。但是,在执行读取操作时,它只会返回一堆zeors,或者接近short的最大值的很多数字。我真的被卡住了,如果有人能帮助我,我会非常友好。这是我的代码:Android:AudioRecord.read()返回垃圾
public class AudioIn extends Thread {
public static final int ERROR_RECORD_INIT = -1;
public static final int ERROR_RECORD_NOTIFICATION = -2;
public static final int ERROR_RECORD_READ = -3;
public static final int SUCCESS = 0;
public static final int audioFrequency = 44100;
public static final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
public static final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
final int ShortsReadPerCycle = 1024;
private boolean capture = true;
private AudioRecord recorder;
private int effectiveCaptureBufferSize;
private short[] buffer;
private AudioInHandler handler;
public AudioIn()
{
int minDeviceBuffer = AudioRecord.getMinBufferSize(audioFrequency, channelConfig, audioFormat);
Log.d("AudioIn", "Minimum device capture buffer is: " + Integer.toString(minDeviceBuffer) + " bytes");
effectiveCaptureBufferSize = minDeviceBuffer;
Log.d("AudioIn", "Setting capture buffer size to " + effectiveCaptureBufferSize + " bytes");
}
public void close()
{
capture = false;
}
public int samplesPerBuffer()
{
return effectiveCaptureBufferSize/2;
}
@Override
public void run() {
// TODO Auto-generated method stub
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
try
{
recorder = new AudioRecord(AudioSource.MIC, audioFrequency, channelConfig, audioFormat, effectiveCaptureBufferSize);
}
catch (Throwable t)
{
handler.onError(ERROR_RECORD_INIT);
return;
}
recorder.startRecording();
while(capture)
{
buffer = new short[ShortsReadPerCycle];
int shortsRead = recorder.read(buffer, 0, buffer.length);
if (shortsRead < 0)
{
new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
handler.onError(ERROR_RECORD_READ);
}
}.run();
this.close();
}
else
{
new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
handler.onNewData(buffer);
}
}.run();
}
}
Log.d("AudioIn.run()", "Stopping AudioRecord...");
recorder.stop();
Log.d("AudioIn.run()", "Stopped AudioRecord, now releasing...");
recorder.release();
Log.d("AudioIn.run()", "AudioRecord released");
recorder = null;
}
public void setHandler(AudioInHandler handler) {
this.handler = handler;
}
}
答
在AudioRecord上调用read()一次并不能确保填充整个short []。您应该检查返回的“shortsRead”以获取实际的短读数并继续调用read(),直到short []被填充。示例代码如下。
private void readFully(short[] data, int off, int length) {
int read;
while (length > 0) {
read = mRec.read(data, off, length);
length -= read;
off += read;
}
}
在录制循环
while (!released) {
// fill the pktBuf
short[] pktBuf = new short[pktSize];
readFully(pktBuf, 0, pktSize);
// Do something
}
这样,每次调用阅读()制成,我们增加的“读”偏移量和减少由“读”剩余长度,继续阅读,直到剩余长度达到0为止。然后,您将获得一个填满的短片[]和录制的音频数据。同样,当你写数据到AudioTrack时,你必须做同样的事情“writeFully()”,以确保整个short []被写入到AudioTrack中。
希望它有帮助。