当前位置:   article > 正文

audiotrack分析_audiotrack是什么意思

audiotrack是什么意思
首先总结一下AudioTrack
AudioTrack字面意思是音轨,可以理解为一路音频的来源。
JAVA层也有AudioTrack的概念,但只是简单的封装,这里不介绍了。只介绍Native JNI的AT


AT 向下传送数据,有两种方式:
1,主动push方式,(对AF来说是被动方式)
AT调用write函数把音频数据“push”到AudioTrack中。
2,被动pull方式,(对AF来说是主动方式)
AF调用callback,从AT获取数据

从另外一个维度来看,还有两种方式:
1,static方式,一次性把数据全传送给AF
延时大,简单高效,适用于提示音等操作
2,stream方式,数据一点点的传送给AF,一块一块的传送
延时小,不受文件大小限制。流媒体播放只能用这种。

下面结合代码总结一下AT的初始化,以及运行起来的流程问题。

开始播放时,JAVA层用JNI调用native函数
  1. static int android_media_AudioTrack_native_setup(....)
  2. {
  3. sp<AudioTrack> lpTrack = new AudioTrack();//初始化track对象
  4. switch (memoryMode) {
  5. case MODE_STREAM:
  6. lpTrack->set( //给track设置好参数
  7. atStreamType,// stream type
  8. sampleRateInHertz,
  9. format,// word length, PCM
  10. nativeChannelMask,
  11. frameCount,
  12. AUDIO_OUTPUT_FLAG_NONE,
  13. audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
  14. 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
  15. 0,// shared mem //stream模式不用共享内存
  16. true,// thread can call Java
  17. sessionId);// audio session ID
  18. break;
  19. case MODE_STATIC:
  20. // AudioTrack is using shared memory
  21. lpTrack->set(
  22. atStreamType,// stream type
  23. sampleRateInHertz,
  24. format,// word length, PCM
  25. nativeChannelMask,
  26. frameCount,
  27. AUDIO_OUTPUT_FLAG_NONE,
  28. audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
  29. 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
  30. lpJniStorage->mMemBase,// shared mem //static模式使用共享内存
  31. true,// thread can call Java
  32. sessionId);// audio session ID
  33. break;
  34. }

  1. static int android_media_AudioTrack_native_setup(....)
  2. {
  3. sp<AudioTrack> lpTrack = new AudioTrack();//初始化track对象
  4. switch (memoryMode) {
  5. case MODE_STREAM:
  6. lpTrack->set( //给track设置好参数
  7. atStreamType,// stream type
  8. sampleRateInHertz,
  9. format,// word length, PCM
  10. nativeChannelMask,
  11. frameCount,
  12. AUDIO_OUTPUT_FLAG_NONE,
  13. audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
  14. 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
  15. 0,// shared mem //stream模式不用共享内存
  16. true,// thread can call Java
  17. sessionId);// audio session ID
  18. break;
  19. case MODE_STATIC:
  20. // AudioTrack is using shared memory
  21. lpTrack->set(
  22. atStreamType,// stream type
  23. sampleRateInHertz,
  24. format,// word length, PCM
  25. nativeChannelMask,
  26. frameCount,
  27. AUDIO_OUTPUT_FLAG_NONE,
  28. audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
  29. 0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
  30. lpJniStorage->mMemBase,// shared mem //static模式使用共享内存
  31. true,// thread can call Java
  32. sessionId);// audio session ID
  33. break;
  34. }

由此可见,AudioTrack::set函数很重要。负责对AT初始化
  1. status_t AudioTrack::set(.... )
  2. {
  3. ....参数检查
  4. audio_io_handle_t output = AudioSystem::getOutput( //根据参数,为这个AT寻找恰当的output输出
  5. streamType,
  6. sampleRate, format, channelMask,
  7. flags,
  8. offloadInfo);
  9. if (cbf != NULL) {
  10. mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
  11. mAudioTrackThread->run("AudioTrack", ANDROID_PRIORITY_AUDIO, 0 /*stack*/);
  12. }//启动一个AT线程,该线程负责处理callback事件,最主要的就是处理EVENT_MORE_DATA 事件,以便通过pull机制存储数据。
  13. // create the IAudioTrack
  14. status_t status = createTrack_l(streamType,
  15. sampleRate,
  16. format,
  17. frameCount,
  18. flags,
  19. sharedBuffer,
  20. output,
  21. 0 /*epoch*/);
  22. //为AT在AF中创建一个Track实例,Track实例是AF和AT交互的桥梁。其handle是IAudioTrack形式的,存储在成员变量mAudioTrack中
  23. }

AT与AF在两个不同进程,其通信依靠的是createTrack_l中创建的位于AF中的Track实例。Track实例在AF中用数组的形式存放。
下面分析一下createTrack_l函数。
  1. status_t AudioTrack::createTrack_l()
  2. {
  3. status_t status;
  4. const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); //获得AF service
  5. sp<IAudioTrack> track = audioFlinger->createTrack(streamType, //调用AF接口来在AF里面创建Track实例
  6. sampleRate,
  7. format == AUDIO_FORMAT_PCM_8_BIT ?
  8. AUDIO_FORMAT_PCM_16_BIT : format,
  9. mChannelMask,
  10. frameCount,
  11. &trackFlags,
  12. sharedBuffer,
  13. output,
  14. tid,
  15. &mSessionId,
  16. mName,
  17. mClientUid,
  18. &status);
  19. sp<IMemory> iMem = track->getCblk();
  20. mAudioTrack = track;
  21. mCblkMemory = iMem;
  22. audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
  23. mCblk = cblk; //获得Audio data的FIFO地址
  24. size_t temp = cblk->frameCount_;
  25. frameCount = temp;
  26. mAwaitBoost = false;
  27. return NO_ERROR;
  28. }

从上面看到,实际是调用了AudioFlinger::createTrack在AF里面创建了Track实例。那么是怎么创建的呢?
  1. sp<IAudioTrack> AudioFlinger::createTrack(...)
  2. {
  3. Mutex::Autolock _l(mLock);
  4. PlaybackThread *thread = checkPlaybackThread_l(output);//通过前面讲过的获得的output,来获得playbackThread
  5. track = thread->createTrack_l(client, streamType, sampleRate, format,
  6. channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus); //在这个playbackThread里面创建Track
  7. trackHandle = new TrackHandle(track); //提供给AT的handle,是IAudioTrack形式的
  8. }

上面我们看到,先利用前面获得的output,来得到output对应的playbackThread,然后在这个playbackThread里面创建了Track,并且为这个Track创建了handle,以提供给AT使用
可以看出,Track的创建,是基于playbackThread的,一个playbackThread可以有多个Track。

前面,我们在AudioTrack::createTrack_l函数里还可以看到audio data的数据区管理部分:
    sp<IMemory> iMem = track->getCblk();
    mAudioTrack = track;
    mCblkMemory = iMem;
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer());
    mCblk = cblk;    
cblk实际上就是指向了audio buffer. 这样,AT就能用write函数写到这片audio data数据区了。

AF章节中,我们介绍过,AP通过调用AudioFlinger::openOutput函数,open了一个outStream, 创建了一个playbackThread, 并且用audio_io_handle_t id 键值来标记。
而output就是这个audio_io_handle_t id值,这样就能通过这个id,找到对应的playbackThread。然后在这个playback里面创建对应的Track。
如果一个playBackThread里面有多个Track,就需要用到AudioMixer来进行mixer混音操作。在AudioMixer章节,我们会详细介绍。

至此,我们大体介绍了AudioTrack是如何初始化的,如何在AudioFlinger中创建Track的,以及如何获得data buffer的。
很多细节我们放在了AudioFlnger和Audio Mixer来做介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/318856
推荐阅读
相关标签
  

闽ICP备14008679号