我有一个Android应用程序,它使用AudioRecord对象记录音频,并通过通知获取数据。 我每64ms请求一次通知,然后获取它,但是当我从AudioRecorder对象执行实际读取时,在某些电话上,它需要几秒钟才能返回。 知道什么可能导致这样的事情吗?
以下是我所做的工作的骨架。
private void GetRecorder()
{
int sampleRate = 16000;
int framePeriod = (int)(sampleRate * 64/ 1000);
int bufferSize = framePeriod * 16/ 8;
recorder = new AudioRecord(AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
recorder.setPositionNotificationPeriod(framePeriod);
recorder.setRecordPositionUpdateListener(this.mRecordListener);
}
private OnRecordPositionUpdateListener mRecordListener = new OnRecordPositionUpdateListener()
{
long start = System.currentTimeMillis();
long readTime = 0;
long maxReadTime = 0;
int frames = 0;
@Override
public void onPeriodicNotification(AudioRecord local_recorder)
{
int buffPos = 0;
int framePeriod = (int)(16000 * 64 / 1000);
long beforeRead = System.currentTimeMillis();
int readBytes = local_recorder.read(bufferQue.pool[queLocation].audioBuffer, buffPos, Math.min(framePeriod, framePeriod - buffPos));
long afterRead = System.currentTimeMillis();
if (afterRead - beforeRead > maxReadTime) maxReadTime = afterRead - beforeRead;
readTime += afterRead - beforeRead;
//This section each 10 secs if didn't get enough frame and print the data
frames++;
if (System.currentTimeMillis() - start > 10000)
{
if (frames < 110)
{
log4j.info("In last 10 secs: " + frames + ", read time was " + readTime + " Max read time was " + maxReadTime);
}
readTime = 0;
maxReadTime = 0;
frames = 0;
start = System.currentTimeMillis();
}
}
@Override
public void onMarkerReached(AudioRecord recorder) {
}
};
答案 0 :(得分:0)
local_recorder.read(bufferQue.pool[queLocation].audioBuffer, buffPos, Math.min(framePeriod, framePeriod - buffPos));
read是一个阻塞方法 - 它将阻塞线程(在你的情况下是主线程),直到有足够的数据来填充你请求的buffersSize - 解决方案是在辅助线程中执行读取。把我上面写的这一行放在一个帖子里 - 就是它。
你要求:&#34;给我64毫秒的录音和#34;。回答:&#34;好的,但等到我有足够的数据。这可能是毛刺,在外面猛攻等等,所以你必须等待......&#34; 。结论:做一个工作线程等待它。继续线程 - &gt;读完 - &gt;暂停线程 - &gt;从听众那里恢复, - &gt;等
答案 1 :(得分:0)
如果您在API级别&gt; = 23的物理设备上进行测试,则read函数需要四个参数..最后一个是设置READ_BLOCKING或READ_NONBLOCKING的选项。