一:录制audioflinger层和audiorecord。
音频系统的对外接口是AudioRecord,它通过iBinder来远程调用Audioflinger的openRecorder函数。AudioRecord构造函数如下:
1:AudioRecord
AudioRecord::AudioRecord(
int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
callback_t cbf,
void* user,
int notificationFrames)
: mStatus(NO_INIT)
{
log_wj("ENTER IN::--%s---%s---/n",__FILE__,__FUNCTION__);
mStatus = set(streamType, sampleRate, format, channelCount,
frameCount, flags, cbf, user, notificationFrames);
}
调用:
status_t AudioRecord::set(int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
callback_t cbf,
void* user,
int notificationFrames,
bool threadCanCallJava)
{
const sp& audioFlinger = AudioSystem::get_audio_flinger();
//获取缓存大小,间接调用我们修改过该函数(经过三次调用中转),返回值为//channelCount*320
AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes);
//远程调用audioFlinger的openrecord函数,openRecord相当于audioflinger为audioRecord
//开辟相应的服务窗口
sp record = audioFlinger->openRecord(getpid(), streamType,
sampleRate, format,
channelCount,
frameCount,
((uint16_t)flags) << 16,
&status);
//创建一个线程用来处理
mClientRecordThread = new ClientRecordThread(*this, threadCanCallJava);
}
AudioRecord相当于一个代理,它的线程是用来处理其它客户的请求。
2:AudioFlinger
sp AudioFlinger::openRecord(
pid_t pid,
int streamType,
uint32_t sampleRate,
int format,
int channelCount,
int frameCount,
uint32_t flags,
status_t *status)
{
// AudioRecord线程
if (mAudioRecordThread == 0) {
LOGE("Audio record thread not started");
lStatus = NO_INIT;
goto Exit;
}
// add client to list
{ // scope for mLock
Mutex::Autolock _l(mLock);
wclient = mClients.valueFor(pid);
if (wclient != NULL) {
client = wclient.promote();
} else {
client = new Client(this, pid);
mClients.add(pid, client);
}
// create new record track. The record track uses one track in mHardwareMixerThread by //convention.
//生成一个recordTrack用来作为数据的中转(audioflinger与audiorecord之间)。
//他们使用audio_track_cblk_t数据结构来传输数据。
recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate, format, channelCount, frameCount, flags);
if (recordTrack->getCblk() == NULL) {
recordTrack.clear();
lStatus = NO_MEMORY;
goto Exit;
}
// return to handle to client------我们的audiorecord。
recordHandle = new RecordHandle(recordTrack);
}
AudioRecord和AudioFlinger操作的都是RecordTrack实例,AudioRecord通过它的执行控制操作(start/stop)和读取操作(read)。Audiorecord的start/stop操作可以理解为一个开关,控制的是AudiorecordThread的运行与否。
Audioflinger则负责从音频设备读取数据放置到
audio_track_cblk_t数据结构中。
二:硬件抽象层