Android 7.0 Audio: AudioSystem相关类浅析

AudioSystem在audio框架中的关系和位置如图所示,

 

 

AudioSystem提供native接口,通过jni访问native提供的audio功能,在native层,有一个对应的AudioSystem.cpp文件

 

 

Jave层主要功能清单可见代码。

 

这里定义了音频流的类型、输入输出器件类型等。

 

对于比较复杂的,如音频输入输出器件的名称如下,

 

输出设备:

1.  DEVICE_OUT_EARPIECE                 : 听筒  

2.    

3.  DEVICE_OUT_SPEAKER                  : 扬声器  

4.    

5.  DEVICE_OUT_WIRED_HEADSET            : 带话筒的耳机  

6.  DEVICE_OUT_WIRED_HEADPHONE          : 不带话筒的耳机  

7.    

8.  DEVICE_OUT_BLUETOOTH_SCO            : 蓝牙.面向连接(SCO)方式:主要用于话音传输  

9.  DEVICE_OUT_BLUETOOTH_SCO_HEADSET    : 蓝牙耳机,带话筒  

10. DEVICE_OUT_BLUETOOTH_SCO_CARKIT     : 蓝牙车载设备  

11. DEVICE_OUT_BLUETOOTH_A2DP           : 蓝牙立体声  

12. DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 蓝牙立体声音耳机  

13. DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER   : 带话筒的  

14.   

15. DEVICE_OUT_AUX_DIGITAL              : 

16. DEVICE_OUT_ANLG_DOCK_HEADSET        : 通过基座连接的模拟有线耳机  

17. DEVICE_OUT_DGTL_DOCK_HEADSET        : 通过基座连接的数字有线耳机  

18. DEVICE_OUT_FM_HEADPHONE             :   FM 耳机

19. DEVICE_OUT_FM_SPEAKER               :FM 扬声器

20. DEVICE_OUT_SPEAKER_SSPA2  

21. DEVICE_OUT_HDMI                     : HDMI接口

22. DEVICE_OUT_FM_TRANSMITTER 

 

输入设

1.  DEVICE_IN_COMMUNICATION         : 手机上的话筒  

2.  DEVICE_IN_AMBIENT               :  

3.  DEVICE_IN_BUILTIN_MIC           : 蓝牙麦克  

4.  DEVICE_IN_BLUETOOTH_SCO_HEADSET : 蓝牙耳机上的话筒  

5.  DEVICE_IN_WIRED_HEADSET         : 有线耳机上的话筒  

6.  DEVICE_IN_AUX_DIGITAL           :  

7.  DEVICE_IN_VOICE_CALL            :  通话中

8.  DEVICE_IN_BACK_MIC              :  

9.  DEVICE_IN_VT_MIC                :   

10. DEVICE_IN_FMRADIO               : FM的输入

 

 

 

 

在native层,AudioSystem主要和AF、APS交互,通过下面几个对象、client和回调,完成向上向下的连接,

sp<IAudioFlinger> AudioSystem::gAudioFlinger;

sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;

audio_error_callback AudioSystem::gAudioErrorCallback = NULL;

dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL;

record_config_callback  AudioSystem::gRecordConfigCallback = NULL;

 

sp<IAudioPolicyService> AudioSystem::gAudioPolicyService;

sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient;

 

 

通过get_audio_flinger,获取AF的服务引用,并创建AFC,促发回调,之后便可以通过af的引用使用AF的服务了,对于AF向上的通知,可以使用client实现,AS的向上通知使用callback。

 

const sp<IAudioFlinger> AudioSystem::get_audio_flinger()

{

    sp<IAudioFlinger> af;

    sp<AudioFlingerClient> afc;

    {

        Mutex::Autolock _l(gLock);

        if (gAudioFlinger == 0) {

            sp<IServiceManager> sm = defaultServiceManager();

            sp<IBinder> binder;

            do {

                binder = sm->getService(String16("media.audio_flinger"));

                if (binder != 0)

                    break;

                ALOGW("AudioFlinger not published, waiting...");

                usleep(500000); // 0.5 s

            } while (true);

            if (gAudioFlingerClient == NULL) {

                gAudioFlingerClient = new AudioFlingerClient();

            } else {

                if (gAudioErrorCallback) {

                    gAudioErrorCallback(NO_ERROR);

                }

            }

            binder->linkToDeath(gAudioFlingerClient);

            gAudioFlinger = interface_cast<IAudioFlinger>(binder);

            LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0);

            afc = gAudioFlingerClient;

        }

        af = gAudioFlinger;

    }

    if (afc != 0) {

        af->registerClient(afc);

    }

    return af;

}

 

 

 

通过get_audio_policy_service,获取APS的服务引用,并创建APSC,之后便可以通过af的引用使用APS的服务了,对于APS向上的通知,可以使用client实现。

const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service()

{

    sp<IAudioPolicyService> ap;

    sp<AudioPolicyServiceClient> apc;

    {

        Mutex::Autolock _l(gLockAPS);

        if (gAudioPolicyService == 0) {

            sp<IServiceManager> sm = defaultServiceManager();

            sp<IBinder> binder;

            do {

                binder = sm->getService(String16("media.audio_policy"));

                if (binder != 0)

                    break;

                ALOGW("AudioPolicyService not published, waiting...");

                usleep(500000); // 0.5 s

            } while (true);

            if (gAudioPolicyServiceClient == NULL) {

                gAudioPolicyServiceClient = new AudioPolicyServiceClient();

            }

            binder->linkToDeath(gAudioPolicyServiceClient);

            gAudioPolicyService = interface_cast<IAudioPolicyService>(binder);

            LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0);

            apc = gAudioPolicyServiceClient;

        }

        ap = gAudioPolicyService;

    }

    if (apc != 0) {

        ap->registerClient(apc);

    }

 

    return ap;

}

 

 

AudioFlingerClient和AudioPolicyServiceClient的定义都在AudioSystem.h,实现在AudioSystem.c里面。

 

对于AudioFlingerClient,首先是向AF注册,AF内创建NotificationClient对象,添加到其内部队列,最后AF的player/recorder线程向其客户端发送通道打开事件。

 

void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)

{

    Mutex::Autolock _l(mLock);

    if (client == 0) {

        return;

    }

    pid_t pid = IPCThreadState::self()->getCallingPid();

    {

        Mutex::Autolock _cl(mClientLock);

        if (mNotificationClients.indexOfKey(pid) < 0) {

            sp<NotificationClient> notificationClient = new NotificationClient(this,

                                                                                client,

                                                                                pid);

            ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);

 

            mNotificationClients.add(pid, notificationClient);

 

            sp<IBinder> binder = IInterface::asBinder(client);

            binder->linkToDeath(notificationClient);

        }

}

 

    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {

        mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid);

    }

 

    for (size_t i = 0; i < mRecordThreads.size(); i++) {

        mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid);

    }

}

 

 

事件上,AF通过AFC的方式向AS传递事件使用得并不多,这可以通过mNotificationClients和NotificationClient. mAudioFlingerClient看出,所以这并不是一个主要流程。

 

 

 

AudioSystem的setErrorCallback的简单分析,

 

应用通过setErrorCallback,向java注册自己的回调函数,

    private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();

 

    private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback {

        public void onError(int error, android.hardware.Camera camera) {

            Assert.fail(String.format("Camera error, code: %d", error));

        }

    }

 

 

Java framework里,errorCallbackFromNative将native的状态回调转给应用的监听回调,根据java的逻辑,每个应用进入时必须设置自己的回调,退出可以清空,不保证在后台可以适合回调,因为这里不支持多用户,只支持最新设置的回调。

    public static void setErrorCallback(ErrorCallback cb)

    {

        synchronized (AudioSystem.class) {

            mErrorCallback = cb;

            if (cb != null) {

                cb.onError(checkAudioFlinger());

            }

        }

    }

 

 

    private static void errorCallbackFromNative(int error)

    {

        ErrorCallback errorCallback = null;

        synchronized (AudioSystem.class) {

            if (mErrorCallback != null) {

                errorCallback = mErrorCallback;

            }

        }

        if (errorCallback != null) {

            errorCallback.onError(error);

        }

    }

 

 

在jni层,android_media_AudioSystem_error_callback调用java的errorCallbackFromNative,

static void

android_media_AudioSystem_error_callback(status_t err)

{

    JNIEnv *env = AndroidRuntime::getJNIEnv();

    if (env == NULL) {

        return;

    }

 

    jclass clazz = env->FindClass(kClassPathName);

 

    env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz,

                              "errorCallbackFromNative","(I)V"),

                              check_AudioSystem_Command(err));

 

    env->DeleteLocalRef(clazz);

}

 

向native注册

    AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback);

 

 

Native层,AudioSystem.cpp里,gAudioErrorCallback被设置和回调的地方如下,可见该回调目前只在AF服务获取成功和AFC解除绑定才会使用,即当前这个回调实际并没什么用。

/* static */ void AudioSystem::setErrorCallback(audio_error_callback cb)

{

    Mutex::Autolock _l(gLock);

    gAudioErrorCallback = cb;

}

 

 

const sp<IAudioFlinger> AudioSystem::get_audio_flinger()

{

                if (gAudioErrorCallback) {

                    gAudioErrorCallback(NO_ERROR);

                }

 

 

void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused)

{

        cb = gAudioErrorCallback;

    if (cb) {

        cb(DEAD_OBJECT);

    }

 


AudioManager类提供audio相关的控制接口,包括音量设置、通道控制、音频焦点控制、音效设置、参数设置、振铃模式等等。使用Context.getSystemServiceContext.AUDIO_SERVICE)来得到这个类的一个实例

 

在应用侧,如下,只需获取服务实例,就可以使用服务接口了。

private AudioManager aManger;

aManger = (AudioManager) getSystemService(Service.AUDIO_SERVICE);

 

aManger.adjustStreamVolume(AudioManager.STREAM_MUSIC, 

                        AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);

 

 

 

AudioManager只是一个功能的接口类和封装类,其功能主要是由AudioService和AudioSystem完成的,通过IAudioService sService和AudioSystem 调用功能的方法。

private static IAudioService sService;

 

    private static IAudioService getService()

    {

        if (sService != null) {

            return sService;

        }

        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);

        sService = IAudioService.Stub.asInterface(b);

        return sService;

    }

 

    public boolean isMicrophoneMute() {

        return AudioSystem.isMicrophoneMuted();

    }

 

 

AudioService是java层的Audio服务类,在SystemServer里被启动,之后就可以被应用使用。

 

private void startOtherServices() {

            traceBeginAndSlog("StartAudioService");

            mSystemServiceManager.startService(AudioService.Lifecycle.class);

            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

 

 

 

AudioService extendsIAudioService.Stub,它内部有handler、callback、receiver来维护整个服务的运行,再借助AudioSystem、BT、Soundpoll、mediaplayer、mediaRecorder等中间类,实现audio的功能。

public class AudioService extends IAudioService.Stub {

    /** @see AudioSystemThread */

    private AudioSystemThread mAudioSystemThread;

    /** @see AudioHandler */

    private AudioHandler mAudioHandler;

 

private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();

 

 

    // BluetoothHeadset API to control SCO connection

    private BluetoothHeadset mBluetoothHeadset;

 

    // Bluetooth headset device

    private BluetoothDevice mBluetoothHeadsetDevice;

 

    private volatile IRingtonePlayer mRingtonePlayer;

 

    private final MediaFocusControl mMediaFocusControl;

 

    private SoundPool mSoundPool;

 

 

 

 

要清楚的几个概念,

 

Mode:设置电话音频状态的模式

    /* modes for setPhoneState, must match AudioSystem.h audio_mode */

    public static final int MODE_INVALID            = -2;

    public static final int MODE_CURRENT            = -1;

    public static final int MODE_NORMAL             = 0;

    public static final int MODE_RINGTONE           = 1;

    public static final int MODE_IN_CALL            = 2;

    public static final int MODE_IN_COMMUNICATION   = 3;

    public static final int NUM_MODES               = 4;

 

 

 

 

音量:分不同stream类型设置音量大小

    /* The default audio stream */

    public static final int STREAM_DEFAULT = -1;

    /* The audio stream for phone calls */

    public static final int STREAM_VOICE_CALL = 0;

    /* The audio stream for system sounds */

    public static final int STREAM_SYSTEM = 1;

    /* The audio stream for the phone ring and message alerts */

    public static final int STREAM_RING = 2;

    /* The audio stream for music playback */

    public static final int STREAM_MUSIC = 3;

    /* The audio stream for alarms */

    public static final int STREAM_ALARM = 4;

    /* The audio stream for notifications */

    public static final int STREAM_NOTIFICATION = 5;

    /* @hide The audio stream for phone calls when connected on bluetooth */

    public static final int STREAM_BLUETOOTH_SCO = 6;

    /* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */

    public static final int STREAM_SYSTEM_ENFORCED = 7;

    /* @hide The audio stream for DTMF tones */

    public static final int STREAM_DTMF = 8;

    /* @hide The audio stream for text to speech (TTS) */

    public static final int STREAM_TTS = 9;

 

 

这两个类具体的代码分析会穿插在其他的业务流程里面。


发布了96 篇原创文章 · 获赞 40 · 访问量 29万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章