我一直在开发一款可以实时播放麦克风音频的应用。 它设置了一个AudioRecorder,它没有任何错误。但是,在执行读取操作时,它只返回一堆zeors,或者接近short的最大值的大量数字。我真的被困了,如果有人能帮助我,那将是非常友好的。这是我的代码:
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;
}
}
答案 0 :(得分:3)
在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
}
这样,每当调用read()时,我们将偏移量增加“read”并减去“read”的剩余长度,继续读取直到剩余长度达到0.然后你将得到一个填充短[]录制音频数据。
类似地,当您将数据写入AudioTrack时,您必须执行相同的操作“writeFully()”,以确保将整个short []写入AudioTrack。
希望它有所帮助。