录音相关的处理流程

一.AudioRecord录音的初始化设置
AudioRecord::set
 ->
AudioSystem::getInput
 ->
调用IAudioPolicyService.cpp文件中的
BpAudioPolicyService的getInput函数
    remote()->transact(GET_INPUT, data, &reply);
BnAudioPolicyService::onTransact(
case GET_INPUT:
    audio_io_handle_t input = getInput(inputSource,
                                   samplingRate,
                                   format,
                                   channels,
                                   acoustics); // 调用的是AudioPolicyService::getInput函数
 ->
AudioPolicyService::getInput
 ->
AudioPolicyManagerBase::getInput
    mpClientInterface->openInput
 ->
AudioPolicyService::openInput
 ->
BpAudioFlinger的openInput函数
 ->
AudioFlinger::openInput
    mAudioHardware->openInputStream
 ->
AudioHardwareALSA::openInputStream
    err = mALSADevice->open(&(*it), devices, mode(), 0);

    in = new AudioStreamInALSA(this, &(*it), acoustics);
    err = in->set(format, channels, sampleRate);
 ->
alsa_default.cpp
调用s_open函数
ALSAStreamOps::set
    if (rate && *rate > 0) {
        if (mHandle->sampleRate != *rate) {
            LOGE("%s L%d  mHandle->sampleRate = %d, return BAD_VALUE %d ", __FUNCTION__, __LINE__,   mHandle->sampleRate, BAD_VALUE);
            return BAD_VALUE;
        }
    }
E/AudioHardwareALSA( 1181): set L123  mHandle->sampleRate = 8000, return BAD_VALUE -22 // 如果采样率不是8000,则返回BAD_VALUE
E/AudioHardwareALSA( 1181): openInputStream L314 in->set err = -22
// BAD_VALUE的定义是
BAD_VALUE           = -EINVAL,
#define EINVAL        3
按照以上定义,BAD_VALUE的值应该是-3,但log输出的值是-22,很奇怪。

----------------------------------------------------------------------------------
二.录音start函数的处理流程
1.如果是录像,则录像中的音频录制的调用顺序是:
MPEG4Writer::start
->
MPEG4Writer::startWriterThread()
->
MPEG4Writer::startTracks
->
MPEG4Writer::Track::start
->
录像时,video track是CameraSource,即调用CameraSource::start函数
audio track是AMRNBEncoder,即调用AMRNBEncoder::start函数
->
2.如果是单纯的录音操作,则直接走下面的路程:
AudioSource::start
->
AudioRecord::start()
->
IAudioRecord::start()
如果返回值为DEAD_OBJECT,则调用
->
AudioRecord::openRecord
  ->
  AudioFlinger::openRecord
  ->
  返回RecordHandle对象
  ->
  AudioFlinger::RecordHandle::start()
  ->
  AudioFlinger::RecordThread::start
  ->
  AudioSystem::startInput(mId);
  ->
  AudioPolicyService::startInput
  ->
  AudioPolicyManagerBase::startInput

如果AudioRecord::openRecord返回NO_ERROR,则继续调用IAudioRecord::start()
如果IAudioRecord::start()返回NO_ERROR,则启动ClientRecordThread线程。

----------------------------------------------------------------------------------
三.AudioRecord开始录音的处理流程
1.frameworks\base\media\java\android\media\AudioRecord.java文件中的
startRecording()函数
    // start recording
    synchronized(mRecordingStateLock) { // 一直处于同步状态,同一时间只能有一个录音
        if (native_start() == SUCCESS) { // 调用native方法
            mRecordingState = RECORDSTATE_RECORDING;
        }
    }
->
2.native_start对应frameworks\base\core\jni\android_media_AudioRecord.cpp文件中的
android_media_AudioRecord_start 函数
取得AudioRecord对象lpRecorder,然后调用lpRecorder->start()的函数,开始录音
->
3.frameworks\base\media\libmedia\AudioRecord.cpp文件的
AudioRecord::start()函数
3.1 取得ClientRecordThread对象t
3.2 调用IAudioRecord对象mAudioRecord->start()
(1)如果返回DEAD_OBJECT,则执行AudioRecord::openRecord函数,调用IAudioFlinger的openRecord函数打开录音设备,然后再执行mAudioRecord->start()开始录音


发布了270 篇原创文章 · 获赞 276 · 访问量 379万+
展开阅读全文

安卓两个录音线程冲突的问题?

03-09

安卓两个录音线程冲突的问题:我在做一个音频制作的安卓项目,用到了一个第三方JNI库。有一个活动里我想在按下一个按钮时,同时开始录音(用AudioRecord)和用麦克风检测外界声音的频率(开启JNI,然后process不停调用JNI里的一个检测函数)。 但很明显发生了冲突,如果是前者先开始录音,后者检测不到东西,用来存储检测到的数值的arraylist的是空的;如果后者先开始不停检测,前者录不到任何声音,只能得到一个空的的wav文件。很明显他们两个的数据源都是MediaRecorder.AudioSource.MIC。 因为JNI方法是无法改变的,一定是用麦克风当数据源,所以只能改我的录音机来让他们两个都能检测到声音。 【因为像全民K歌、唱吧、酷狗等软件,都有检测用户声音的频率对其进行打分的功能,而且同时进行了录音线程,没有发生任何冲突,我就感觉很不解! 我不相信他们是对录音得到的pcm切片进行分析得到的检测频率,因为这会有极大的延迟。】 【有一个同事说了他的思路。像任何安卓手机在打电话时,它的通话线程是一定要占用MIC的,而且无法改动。他提到了手机内录(打电话的时候同步录音)软件的开发,先打开那个软件,让软件得到.AudioSource.MIC,但软件保存录音后又会做一个数据输出口。再进行通话时,通话的线程用的AudioSource.MIC是假的,是内录软件的输出,蒙骗了通话线程,这样就实现了同步录音和通话。不知道这个软件之间的蒙骗,能不能做在我们自己的软件内部,就是把我的“录音机”做成“内录软件”】 急需解答!! 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览