Android学习(十)AudioFlinger(2)

AudioFlinger2

查看Track的构造函数:

AudioFlinger::PlaybackThread::Track::Track(

            const wp<ThreadBase>& thread,

            const sp<Client>& client,

            int streamType,

            uint32_t sampleRate,

            int format,

            int channelCount,

            int frameCount,

            const sp<IMemory>& sharedBuffer,

            int sessionId)

    :   TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId),

    mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL),

    mAuxEffectId(0), mHasVolumeController(false)

{

    if (mCblk != NULL) {à在父类TrackBase中创建

        sp<ThreadBase> baseThread = thread.promote();

        if (baseThread != 0) {

            PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();

            mName = playbackThread->getTrackName_l();

            mMainBuffer = playbackThread->mixBuffer();

        }

        mVolume[0] = 1.0f;

        mVolume[1] = 1.0f;

        mStreamType = streamType;

        // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack

        mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);

    }

}

查看父类TrackBase的构造函数:

AudioFlinger::ThreadBase::TrackBase::TrackBase(

            const wp<ThreadBase>& thread,

            const sp<Client>& client,

            uint32_t sampleRate,

            int format,

            int channelCount,

            int frameCount,

            uint32_t flags,

            const sp<IMemory>& sharedBuffer,

            int sessionId)

    :   RefBase(),

        mThread(thread),

        mClient(client),

        mCblk(0),

        mFrameCount(0),

        mState(IDLE),

        mClientTid(-1),

        mFormat(format),

        mFlags(flags & ~SYSTEM_FLAGS_MASK),

        mSessionId(sessionId)

{

   size_t size = sizeof(audio_track_cblk_t);à得到audio_track_cblk_t的大小

   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);

   if (sharedBuffer == 0) {

       size += bufferSize;à共享内存中前面为audio_track_cblk_t,后面为数据

   }

 

   if (client != NULL) {

        mCblkMemory = client->heap()->allocate(size);à根据size大小创建共享内存

        if (mCblkMemory != 0) {

            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());àpointer返回共享内存首地址,强制转换为audio_track_cblk_t类型

            if (mCblk) { // construct the shared structure in-place.

                new(mCblk) audio_track_cblk_t();

                // clear all buffers

                mCblk->frameCount = frameCount;

                mCblk->sampleRate = sampleRate;

                mCblk->channelCount = (uint8_t)channelCount;

                if (sharedBuffer == 0) {

                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);

                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));à清空数据区

                    // Force underrun condition to avoid false underrun callback until first data is

                    // written to buffer (other flags are cleared)

                    mCblk->flags = CBLK_UNDERRUN_ON;à初始化flag

                }

 

new(mCblk) audio_track_cblk_t();是一个placement new操作,目的是在已经分配的内存中创建一个对象(普通的new是无法完成的)。这里采用placement new将使audio_track_cblk_t创建在共享内存上,从而能使多个进程看见并使用。

上面分析可知:

  • Track创建了共享内存

  • audio_track_cblk_t对象通过placement new创建在共享内存中

查看AudioFlinger::createTrack

sp<IAudioTrack> AudioFlinger::createTrack(..)

{

sp<TrackHandle> trackHandle;

track = thread->createTrack_l(client, streamType, sampleRate, format,

                channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);

trackHandle = new TrackHandle(track);

return trackHandle;

}

可见AudioFlinger::createTrack返回的是一个TrackHandle对象,它是Track的代理模式,完成Track本身不具备的Binder通信的功能。

转载于:https://my.oschina.net/honeyandroid/blog/517074

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学习Android音频系统和ALSA框架,您需要掌握以下知识点: 1. Linux内核音频子系统的工作原理:包括音频驱动程序、音频设备、音频接口等。 2. ALSA框架的工作原理:包括alsa-lib、alsa-utils、alsa-plugins等组成部分,以及与音频设备驱动的交互方式。 3. Android音频系统架构:包括Audio HAL、AudioFlingerAudioTrack、AudioRecord、AudioEffect等模块的作用和相互关系。 4. Android音频API的使用:包括MediaPlayer、SoundPool、AudioTrack、AudioRecord等类的使用方法和音频数据的处理。 5. Android音频应用程序的开发:包括音频录制、音频播放、音频处理等方面的实现技巧。 下面是学习Android音频系统和ALSA框架的具体步骤: 1. 学习Linux内核音频子系统的工作原理,可以参考Linux内核开发相关的书籍和网上资料。 2. 学习ALSA框架的工作原理,可以参考ALSA官方文档和相关书籍,也可以通过查看Android源代码中的alsa-lib、alsa-utils等目录中的代码来了解。 3. 学习Android音频系统架构,可以参考官方文档和书籍,也可以通过查看Android源代码中的Audio HAL、AudioFlinger等目录中的代码来了解。 4. 学习Android音频API的使用,可以参考官方文档和书籍,也可以通过查看Android源代码中的MediaPlayer、SoundPool、AudioTrack、AudioRecord等类的实现代码来了解。 5. 学习Android音频应用程序的开发,可以参考官方文档和书籍,也可以通过查看Android源代码中的音频应用程序的实现代码来了解。 总之,学习Android音频系统和ALSA框架需要掌握一定的Linux内核知识和Android开发经验,需要不断地阅读相关文档和代码,并进行实践和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值