今天来看看如何将AudioEffect与AudioTrack关联起来。


*****************************************源码*************************************************
    //Test case 1.7: test auxiliary effect attachement on AudioTrack    @LargeTest    public void test1_7AuxiliaryOnAudioTrack() throws Exception {        boolean result = false;        String msg = "test1_7AuxiliaryOnAudioTrack()";        try {            AudioTrack track = new AudioTrack(                                        AudioManager.STREAM_MUSIC,                                        44100,                                        AudioFormat.CHANNEL_OUT_MONO,                                        AudioFormat.ENCODING_PCM_16BIT,                                        AudioTrack.getMinBufferSize(44100,                                                                    AudioFormat.CHANNEL_OUT_MONO,                                                                    AudioFormat.ENCODING_PCM_16BIT),                                                                    AudioTrack.MODE_STREAM);            assertNotNull(msg + ": could not create AudioTrack", track);            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,                    AudioEffect.EFFECT_TYPE_NULL,                    0,                    0);            track.attachAuxEffect(effect.getId());            track.setAuxEffectSendLevel(1.0f);            result = true;            effect.release();            track.release();        } catch (IllegalArgumentException e) {            msg = msg.concat(": Equalizer not found");            loge(msg, ": Equalizer not found");        } catch (UnsupportedOperationException e) {            msg = msg.concat(": Effect library not loaded");            loge(msg, ": Effect library not loaded");        }        assertTrue(msg, result);    }

**********************************************************************************************
源码路径:
frameworks\base\media\tests\mediaframeworktest\src\com\android\mediaframeworktest\functional\MediaAudioEffectTest.java


#######################说明################################
    //Test case 1.7: test auxiliary effect attachement on AudioTrack    @LargeTest    public void test1_7AuxiliaryOnAudioTrack() throws Exception {        boolean result = false;        String msg = "test1_7AuxiliaryOnAudioTrack()";        try {            AudioTrack track = new AudioTrack(                                        AudioManager.STREAM_MUSIC,                                        44100,                                        AudioFormat.CHANNEL_OUT_MONO,                                        AudioFormat.ENCODING_PCM_16BIT,                                        AudioTrack.getMinBufferSize(44100,                                                                    AudioFormat.CHANNEL_OUT_MONO,                                                                    AudioFormat.ENCODING_PCM_16BIT),                                                                    AudioTrack.MODE_STREAM);            assertNotNull(msg + ": could not create AudioTrack", track);            AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB,                    AudioEffect.EFFECT_TYPE_NULL,                    0,                    0);// 此处getId获取的是调用JNI接口native_setup时得到的            track.attachAuxEffect(effect.getId());// +++++++++++++++++++++++++++++attachAuxEffect+++++++++++++++++++++++++++++++++++    /**     * Attaches an auxiliary effect to the audio track. A typical auxiliary     * effect is a reverberation effect which can be applied on any sound source     * that directs a certain amount of its energy to this effect. This amount     * is defined by setAuxEffectSendLevel().     * {@see #setAuxEffectSendLevel(float)}.     * <p>After creating an auxiliary effect (e.g.     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling     * this method to attach the audio track to the effect.     * <p>To detach the effect from the audio track, call this method with a     * null effect id.     *     * @param effectId system wide unique id of the effect to attach     * @return error code or success, see {@link #SUCCESS},     *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}     */    public int attachAuxEffect(int effectId) {        if (mState != STATE_INITIALIZED) {            return ERROR_INVALID_OPERATION;        }        return native_attachAuxEffect(effectId);// ++++++++++++++++++++++++++++android_media_AudioTrack_attachAuxEffect++++++++++++++++++++++++++++++++++++static jint android_media_AudioTrack_attachAuxEffect(JNIEnv *env,  jobject thiz,        jint effectId) {    AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(                thiz, javaAudioTrackFields.nativeTrackInJavaObj);    if (lpTrack) {        return android_media_translateErrorCode( lpTrack->attachAuxEffect(effectId) );// ++++++++++++++++++++++++++++++AudioTrack::attachAuxEffect++++++++++++++++++++++++++++++++++status_t AudioTrack::attachAuxEffect(int effectId){    LOGV("attachAuxEffect(%d)", effectId);// mAudioTrack在函数AudioTrack::createTrack中被赋值,其最终指向的其实是一个TrackHandle对象    status_t status = mAudioTrack->attachAuxEffect(effectId);// ++++++++++++++++++++++++++++++AudioFlinger::TrackHandle::attachAuxEffect++++++++++++++++++++++++++++++++++status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId){    return mTrack->attachAuxEffect(EffectId);// ++++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::Track::attachAuxEffect++++++++++++++++++++++++++++++++++status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId){    status_t status = DEAD_OBJECT;    sp<ThreadBase> thread = mThread.promote();    if (thread != 0) {       PlaybackThread *playbackThread = (PlaybackThread *)thread.get();       status = playbackThread->attachAuxEffect(this, EffectId);// ++++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::attachAuxEffect++++++++++++++++++++++++++++++++++status_t AudioFlinger::PlaybackThread::attachAuxEffect(        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId){    Mutex::Autolock _l(mLock);    return attachAuxEffect_l(track, EffectId);// +++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::attachAuxEffect_l+++++++++++++++++++++++++++++++++++status_t AudioFlinger::PlaybackThread::attachAuxEffect_l(        const sp<AudioFlinger::PlaybackThread::Track> track, int EffectId){    status_t status = NO_ERROR;// 如果EffectId为0,其实是清楚effect    if (EffectId == 0) {        track->setAuxBuffer(0, NULL);// +++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::Track::setAuxBuffer+++++++++++++++++++++++++++++++++++void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer){// 函数AudioFlinger::PlaybackThread::detachAuxEffect_l中调用了函数AudioFlinger::PlaybackThread::Track::auxEffectId来得到mAuxEffectId    mAuxEffectId = EffectId;// 函数AudioFlinger::MixerThread::prepareTracks_l中会调用函数AudioFlinger::PlaybackThread::Track::auxBuffer获取mAuxBuffer//            mAudioMixer->setParameter(//                AudioMixer::TRACK,//                AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());    mAuxBuffer = buffer;}// -----------------------------AudioFlinger::PlaybackThread::Track::setAuxBuffer-----------------------------------    } else {        // Auxiliary effects are always in audio session AudioSystem::SESSION_OUTPUT_MIX        sp<EffectModule> effect = getEffect_l(AudioSystem::SESSION_OUTPUT_MIX, EffectId);// +++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::getEffect_l+++++++++++++++++++++++++++++++++++sp<AudioFlinger::EffectModule> AudioFlinger::PlaybackThread::getEffect_l(int sessionId, int effectId){    sp<EffectModule> effect;// 先得到chain    sp<EffectChain> chain = getEffectChain_l(sessionId);// ++++++++++++++++++++++++++++AudioFlinger::PlaybackThread::getEffectChain_l++++++++++++++++++++++++++++++++++++sp<AudioFlinger::EffectChain> AudioFlinger::PlaybackThread::getEffectChain_l(int sessionId){    sp<EffectChain> chain;    size_t size = mEffectChains.size();    for (size_t i = 0; i < size; i++) {        if (mEffectChains[i]->sessionId() == sessionId) {// 函数AudioFlinger::PlaybackThread::addEffectChain_l会向mEffectChains添加成员// 函数AudioFlinger::PlaybackThread::createEffect_l和AudioFlinger::PlaybackThread::addEffect_l中,// 会判断指定session Id对应的effect chain是否存在,若不存在,创建一个,并调用mEffectChains添加到mEffectChains中            chain = mEffectChains[i];            break;        }    }    return chain;}// ----------------------------AudioFlinger::PlaybackThread::getEffectChain_l------------------------------------    if (chain != 0) {// 再根据effect Id从chain上得到effect        effect = chain->getEffectFromId_l(effectId);// +++++++++++++++++++++++++++AudioFlinger::EffectChain::getEffectFromId_l+++++++++++++++++++++++++++++++++++++// getEffectFromId_l() must be called with PlaybackThread::mLock heldsp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id){    sp<EffectModule> effect;    size_t size = mEffects.size();    for (size_t i = 0; i < size; i++) {        // by convention, return first effect if id provided is 0 (0 is never a valid id)        if (id == 0 || mEffects[i]->id() == id) {// 函数AudioFlinger::EffectChain::addEffect_l会向mEffects中添加effect// 函数AudioFlinger::PlaybackThread::createEffect_l和AudioFlinger::PlaybackThread::addEffect_l中,// 会调用函数AudioFlinger::EffectChain::addEffect_l            effect = mEffects[i];            break;        }    }    return effect;}// ---------------------------AudioFlinger::EffectChain::getEffectFromId_l-------------------------------------    }    return effect;}// -----------------------------AudioFlinger::PlaybackThread::getEffect_l-----------------------------------        if (effect != 0) {            if ((effect->desc().flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {                track->setAuxBuffer(EffectId, (int32_t *)effect->inBuffer());            } else {                status = INVALID_OPERATION;            }        } else {            status = BAD_VALUE;        }    }    return status;}// -----------------------------AudioFlinger::PlaybackThread::attachAuxEffect_l-----------------------------------}// ------------------------------AudioFlinger::PlaybackThread::attachAuxEffect----------------------------------    }    return status;}// ------------------------------AudioFlinger::PlaybackThread::Track::attachAuxEffect----------------------------------}// ------------------------------AudioFlinger::TrackHandle::attachAuxEffect----------------------------------    if (status == NO_ERROR) {        mAuxEffectId = effectId;    }    return status;}// ------------------------------AudioTrack::attachAuxEffect----------------------------------    } else {        jniThrowException(env, "java/lang/IllegalStateException",            "Unable to retrieve AudioTrack pointer for attachAuxEffect()");        return AUDIOTRACK_ERROR;    }}// ----------------------------android_media_AudioTrack_attachAuxEffect------------------------------------    }// -----------------------------attachAuxEffect-----------------------------------            track.setAuxEffectSendLevel(1.0f);// +++++++++++++++++++++++++++++++setAuxEffectSendLevel+++++++++++++++++++++++++++++++++    /**     * Sets the send level of the audio track to the attached auxiliary effect     * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0.     * <p>By default the send level is 0, so even if an effect is attached to the player     * this method must be called for the effect to be applied.     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,     * so an appropriate conversion from linear UI input x to level is:     * x == 0 -> level = 0     * 0 < x <= R -> level = 10^(72*(x-R)/20/R)     *     * @param level send level scalar     * @return error code or success, see {@link #SUCCESS},     *    {@link #ERROR_INVALID_OPERATION}     */    public int setAuxEffectSendLevel(float level) {        if (mState != STATE_INITIALIZED) {            return ERROR_INVALID_OPERATION;        }        // clamp the level        if (level < getMinVolume()) {            level = getMinVolume();        }        if (level > getMaxVolume()) {            level = getMaxVolume();        }        native_setAuxEffectSendLevel(level);// ++++++++++++++++++++++++++++++android_media_AudioTrack_setAuxEffectSendLevel++++++++++++++++++++++++++++++++++static voidandroid_media_AudioTrack_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level ){    AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(        thiz, javaAudioTrackFields.nativeTrackInJavaObj);    if (lpTrack == NULL ) {        jniThrowException(env, "java/lang/IllegalStateException",            "Unable to retrieve AudioTrack pointer for setAuxEffectSendLevel()");        return;    }    lpTrack->setAuxEffectSendLevel(level);// +++++++++++++++++++++++++++++AudioTrack::setAuxEffectSendLevel+++++++++++++++++++++++++++++++++++status_t AudioTrack::setAuxEffectSendLevel(float level){    LOGV("setAuxEffectSendLevel(%f)", level);    if (level > 1.0f) {        return BAD_VALUE;    }    mSendLevel = level;// 函数AudioFlinger::MixerThread::prepareTracks_l中有使用mCblk->sendLevel// va = (uint32_t)(v * cblk->sendLevel);// aux = int16_t(va);// mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);    mCblk->sendLevel = uint16_t(level * 0x1000);    return NO_ERROR;}// -----------------------------AudioTrack::setAuxEffectSendLevel-----------------------------------}// ------------------------------android_media_AudioTrack_setAuxEffectSendLevel----------------------------------        return SUCCESS;    }// -------------------------------setAuxEffectSendLevel---------------------------------            result = true;            effect.release();            track.release();        } catch (IllegalArgumentException e) {            msg = msg.concat(": Equalizer not found");            loge(msg, ": Equalizer not found");        } catch (UnsupportedOperationException e) {            msg = msg.concat(": Effect library not loaded");            loge(msg, ": Effect library not loaded");        }        assertTrue(msg, result);    }

###########################################################


&&&&&&&&&&&&&&&&&&&&&&&总结&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
attachAuxEffect最终会将effect 的in buffer赋值给track对象的auxBuffer。
setAuxEffectSendLevel会将send level保存到audio_track_cblk_t对象中。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

更多相关文章

  1. Android(安卓)EditText得到焦点失去焦点处理方法
  2. 2.20 android连接wifi,解决mWifiManager.addNetwork(info)=-1
  3. 代码讲解Android(安卓)Scroller、VelocityTracker
  4. Android(安卓)GPS获得经纬度并得到该坐标精确地址
  5. 《Android系统学习》第十章:Android消息处理、消息循环和消息队列
  6. Android(安卓)服务(本地服务示例)(二)
  7. Android(安卓)Audio代码分析23 - attachAuxEffect函数
  8. 【笔记】android捕获触摸事件
  9. 箭头函数的基础使用

随机推荐

  1. java8中lambda表达式
  2. FilenameFilter文件名过滤器使用实例
  3. Java核心技术卷I:基础知识(原书第8版):14.
  4. String字符串的应用
  5. java求1-1/3+1/5-1/7+1/9
  6. java GBK字符转换成为UTF-8编码字符
  7. Java 中的一些更深入些的知识。。。
  8. 急找工作,想用java语言做一个小的软件,请高
  9. 开发网站相关知识html和javascript
  10. 为内存密集型应用程序增加JVM最大堆大小