Audio笔记之AudioTrackThread

本文详细探讨了Android中AudioTrack的使用,包括初始化设置、音频数据写入、播放控制等方面,揭示了实现音频播放的关键步骤和技术要点。
摘要由CSDN通过智能技术生成

static jint android_media_AudioTrack_native_setup(
       JNIEnv *env, 
       jobjectthiz, jobject weak_this,        
       jintstreamType, 
       jint sampleRateInHertz, 
       jint javaChannelMask,        
       jint audioFormat, 
       jint buffSizeInBytes, 
       jint memoryMode, 
       jintArray jSession){
    .......

    // initialize the native AudioTrack object  
    switch (memoryMode) {  
    case MODE_STREAM:  
        //STREAM模式,现在没有申请共享内存,后续Track对象通过  
        //AudioFlinger中的Client对象申请heap空间给mCblk进行数据传输  
        lpTrack->set(  
            atStreamType,// stream type  
            sampleRateInHertz,  
            format,// word length, PCM  
            nativeChannelMask,  
            frameCount,  
            AUDIO_OUTPUT_FLAG_NONE,  
            audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)  
            0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack  
            0,// shared mem  
            true,// thread can call Java  
            sessionId);// audio session ID  
        break;  
  
    case MODE_STATIC:  
        // STATIC模式,为AudioTrack分配共享内存区域,大小为buffSizeInBytes  
    //后续会将这些buff分配给track的mCblk进行数据传输  
        if (!lpJniStorage->allocSharedMem(buffSizeInBytes)) {  
            ALOGE("Error creating AudioTrack in static mode: error creating mem heap base");  
            goto native_init_failure;  
        }  
  
        lpTrack->set(  
            atStreamType,// stream type  
            sampleRateInHertz,  
            format,// word length, PCM  
            nativeChannelMask,  
            frameCount,  
            AUDIO_OUTPUT_FLAG_NONE,  
            audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));  
            0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack  
            lpJniStorage->mMemBase,// shared mem  
            true,// thread can call Java  
            sessionId);// audio session ID  
        break;  
  
    default:  
        ALOGE("Unknown mode %d", memoryMode);  
        goto native_init_failure;  
    }
    ......
}

status_t AudioTrack::set(
        audio_stream_type_t streamType,
        uint32_tsampleRate,
        audio_format_tformat,
        audio_channel_mask_tchannelMask,
        intframeCountInt,
        audio_output_flags_t flags,
        callback_tcbf,
        void* user,
        intnotificationFrames,
        constsp<IMemory>& sharedBuffer,
        boolthreadCanCallJava,
        int sessionId,
        transfer_type transferType,
        constaudio_offload_info_t *offloadInfo,
        int uid){
        ......
    /*cbf为JNI层设置的回调函数
       因为cbf是audioCallback不为空,所以这里会启动一个AudioTrackThread线程。
       这个线程是用于AudioTrack(native)与AudioTrack(java)间的数据事件通知的,
       这就为上层应用处理事件提供了一个入口,包括:
       EVENT_MORE_DATA = 0,  //请求写入更多数据
       EVENT_UNDERRUN = 1,  //PCM 缓冲发生了underrun
       EVENT_LOOP_END = 2,   //到达loop end,loopcount!=null从loop start重新开始回放
       EVENT_MARKER = 3,     //Playback head在指定的位置,参考setMarkerPosition
       EVENT_NEW_POS = 4,   //Playback head在一个新的位置,参考setPositionUpdatePeriod
       EVENT_BUFFER_END = 5 //Playback head在buffer末尾
       EVENT_NEW_IAUDIOTRACK = 6, //recreate audiotrack
       EVENT_STREAM_END = 7, //AF和HW端数据播放完毕
       EVENT_NEW_TIMESTAMP = 8  //暂时未用
    */    
    if (cbf != NULL) {
       mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
       mAudioTrackThread->run("AudioTrack",ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
    }
    ......
}

//调用java层用户实现的函数</p><p>static void audioCallback(int event, void* user, void *info) {
    audiotrack_callback_cookie*callbackInfo = (audiotrack_callback_cookie *)user;
    {
        Mutex::Autolock l(sLock);
        if(sAudioTrackCallBackCookies.indexOf(callbackInfo) < 0) {
            return;
        }
        callbackInfo->busy =true;    }
 
    switch (event) {
    caseAudioTrack::EVENT_MARKER: {
        JNIEnv *env =AndroidRuntime::getJNIEnv();
        if (user != NULL&& env != NULL) {
           env->CallStaticVoidMethod(
               callbackInfo->audioTrack_class,
               javaAudioTrackFields.postNativeEventInJava,
               callbackInfo->audioTrack_ref, event, 0,0, NULL);
            if(env->ExceptionCheck()) {
               env->ExceptionDescribe();
 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值