当前位置: 首页 > news >正文

营销型单页面网站网络推广策划方案怎么写

营销型单页面网站,网络推广策划方案怎么写,网站建设费入预付款什么科目,手机网站排名优化软件前言: 在 Android 音频系统中,AudioMixer 是音频框架中一个关键的组件,用于处理多路音频流的混音操作。它主要存在于音频回放路径中,是 AudioFlinger 服务的一部分。 上一节我们讲threadloop的时候,提到了一个函数pr…

前言:

在 Android 音频系统中,AudioMixer 是音频框架中一个关键的组件,用于处理多路音频流的混音操作。它主要存在于音频回放路径中,是 AudioFlinger 服务的一部分。

上一节我们讲threadloop的时候,提到了一个函数prepareTracks_l,在这个函数的最后就调用了 mAudioMixer->create、mAudioMixer->setParameter去设置参数,channel、format、volume等等。

AudioMixer继承自 AudioMixerBase,当我们去看AudioMixer的构造函数的时候发现并没有做任何操作
在这里插入图片描述

那他的初始化代码在哪里呢?

走进AudioMixer:

我们看prepareTracks_l内关于mAudioMixer的调用流程就可以发现,他首先调用了create函数,然而Audiomixer内部却没有实现create接口,我们追溯到它的父类,发现在AudioMixerBase对象种定义了create接口并且实现了。

我们粗略的看下create里主要做了什么,代码多我做了删减。

status_t AudioMixerBase::create(int name, audio_channel_mask_t channelMask, audio_format_t format, int sessionId)
{LOG_ALWAYS_FATAL_IF(exists(name), "name %d already exists", name);if (!isValidChannelMask(channelMask)) {ALOGE("%s invalid channelMask: %#x", __func__, channelMask);return BAD_VALUE;}if (!isValidFormat(format)) {ALOGE("%s invalid format: %#x", __func__, format);return BAD_VALUE;}auto t = preCreateTrack();{t->needs = 0;t->volume[0] = 0;...t->channelCount = audio_channel_count_from_out_mask(channelMask);t->enabled = false;t->channelMask = channelMask;t->sessionId = sessionId;t->hook = NULL;...// setBufferProvider(name, AudioBufferProvider *) is required before enable(name)t->sampleRate = mSampleRate;t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;t->mFormat = format;t->mMixerChannelCount = audio_channel_count_from_out_mask(t->mMixerChannelMask);t->mInputFrameSize = audio_bytes_per_frame(t->channelCount, t->mFormat);status_t status = postCreateTrack(t.get());if (status != OK) return status;mTracks[name] = t;return OK;}
}

可以看到除了一开始做了channel和format的判断,后面基本上就是对track的初始化,像volume、channel、format、sampleRate还有Hook的初始化。

初始化完成后就开始调用AudioMixer内部的接口了,我们依次往下看发现还有getUnreleasedFrames、setParameter、setBufferProvider、process等。
我们先看下setParameter,当属性变化的时候就会调用到这里。


void AudioMixer::setParameter(int name, int target, int param, void *value)
{LOG_ALWAYS_FATAL_IF(!exists(name), "invalid name: %d", name);const std::shared_ptr<Track> &track = getTrack(name);int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));int32_t *valueBuf = reinterpret_cast<int32_t*>(value);switch (target) {case TRACK:switch (param) {case CHANNEL_MASK: {const audio_channel_mask_t trackChannelMask =static_cast<audio_channel_mask_t>(valueInt);if (setChannelMasks(name, trackChannelMask,static_cast<audio_channel_mask_t>(track->mMixerChannelMask | track->mMixerHapticChannelMask))) {ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", trackChannelMask);invalidate();}} break;case MAIN_BUFFER:if (track->mainBuffer != valueBuf) {track->mainBuffer = valueBuf;ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);if (track->mKeepContractedChannels) {track->prepareForAdjustChannels(mFrameCount);}invalidate();}break;case AUX_BUFFER:AudioMixerBase::setParameter(name, target, param, value);break;case FORMAT: {audio_format_t format = static_cast<audio_format_t>(valueInt);if (track->mFormat != format) {ALOG_ASSERT(audio_is_linear_pcm(format), "Invalid format %#x", format);track->mFormat = format;ALOGV("setParameter(TRACK, FORMAT, %#x)", format);track->prepareForReformat();invalidate();}} break;case MIXER_FORMAT: {audio_format_t format = static_cast<audio_format_t>(valueInt);if (track->mMixerFormat != format) {track->mMixerFormat = format;ALOGV("setParameter(TRACK, MIXER_FORMAT, %#x)", format);if (track->mKeepContractedChannels) {track->prepareForAdjustChannels(mFrameCount);}}} break;case MIXER_CHANNEL_MASK: {const audio_channel_mask_t mixerChannelMask =static_cast<audio_channel_mask_t>(valueInt);if (setChannelMasks(name, static_cast<audio_channel_mask_t>(track->channelMask | track->mHapticChannelMask),mixerChannelMask)) {ALOGV("setParameter(TRACK, MIXER_CHANNEL_MASK, %#x)", mixerChannelMask);invalidate();}} break;
...default:LOG_ALWAYS_FATAL("setParameter track: bad param %d", param);}break;case RESAMPLE:case RAMP_VOLUME:case VOLUME:AudioMixerBase::setParameter(name, target, param, value);break;case TIMESTRETCH:switch (param) {case PLAYBACK_RATE: {const AudioPlaybackRate *playbackRate =reinterpret_cast<AudioPlaybackRate*>(value);
...} break;default:LOG_ALWAYS_FATAL("setParameter timestretch: bad param %d", param);}break;default:LOG_ALWAYS_FATAL("setParameter: bad target %d", target);}
}

函数的主要结构就是一个switch,首先通过trackId找到对应的track对象,然后去设置对应track的parameter参数,例如 CHANNEL_MASK、FORMAT、MAIN_BUFFER等。

这只是设置参数,那混音在哪里呢?我们继续往下看process

void process() {preProcess();(this->*mHook)();postProcess();
}

这里主要就是调用mHook,mHook是一个函数指针,他会根据不同的场景分别调用不同的函数。

  • process__nop:初始值
  • process__genericResampling:对两路以上的track进行重采样操作
  • process__genericNoResampling:对两路以上的track不进行重采样操作
  • process__validate:这个函数就是根据当前的不同情况将mHook指向不同的函数
  • process__oneTrack16BitsStereoNoResampling:只有一路track,16bit,立体声的时候不进行重采样
process_hook_t mHook = &AudioMixerBase::process__nop;

mHook初始化的时候指向的是process__nop

void invalidate() {mHook = &AudioMixerBase::process__validate;}

process__validate是在invalidate函数里幅值给了mHook 指针。

void AudioMixerBase::process__validate()
{// select the processing hooksmHook = &AudioMixerBase::process__nop;if (mEnabled.size() > 0) {if (resampling) {if (mOutputTemp.get() == nullptr) {mOutputTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);}if (mResampleTemp.get() == nullptr) {mResampleTemp.reset(new int32_t[MAX_NUM_CHANNELS * mFrameCount]);}mHook = &AudioMixerBase::process__genericResampling;} else {// we keep temp arrays around.mHook = &AudioMixerBase::process__genericNoResampling;if (all16BitsStereoNoResample && !volumeRamp) {if (mEnabled.size() == 1) {const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];if ((t->needs & NEEDS_MUTE) == 0) {// The check prevents a muted track from acquiring a process hook.//// This is dangerous if the track is MONO as that requires// special case handling due to implicit channel duplication.// Stereo or Multichannel should actually be fine here.mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK,t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat,t->useStereoVolume());}}}}}
}

这个函数首先使用while循环来遍历每一个track,然后通过 NEEDS_RESAMPLE、NEEDS_AUX、NEEDS_CHANNEL_1、NEEDS_MUTE等判断,最终得到resampling、all16BitsStereoNoResample、volumeRamp的值,然后基于这几个值来决定调用,mHook来指向哪一个函数。

至于音频流数据是如何混到一起的,我们后面章节再来进一步分析。


文章转载自:
http://salamandrine.hwbf.cn
http://poloist.hwbf.cn
http://slingshot.hwbf.cn
http://beef.hwbf.cn
http://packplane.hwbf.cn
http://symbolisation.hwbf.cn
http://dago.hwbf.cn
http://maxwell.hwbf.cn
http://renewable.hwbf.cn
http://armscye.hwbf.cn
http://pharmacopoeia.hwbf.cn
http://zonary.hwbf.cn
http://shopper.hwbf.cn
http://nonrestraint.hwbf.cn
http://speak.hwbf.cn
http://avery.hwbf.cn
http://museum.hwbf.cn
http://quinquepartite.hwbf.cn
http://abounding.hwbf.cn
http://finalist.hwbf.cn
http://aveline.hwbf.cn
http://canalisation.hwbf.cn
http://umc.hwbf.cn
http://mary.hwbf.cn
http://crossroad.hwbf.cn
http://isapi.hwbf.cn
http://padding.hwbf.cn
http://beadhouse.hwbf.cn
http://rhinoscopy.hwbf.cn
http://foundry.hwbf.cn
http://rosenhahnite.hwbf.cn
http://amphimixis.hwbf.cn
http://civitan.hwbf.cn
http://martinet.hwbf.cn
http://undulation.hwbf.cn
http://contranatural.hwbf.cn
http://locate.hwbf.cn
http://sensitive.hwbf.cn
http://captainship.hwbf.cn
http://hooter.hwbf.cn
http://drumroll.hwbf.cn
http://saccharolytic.hwbf.cn
http://kromesky.hwbf.cn
http://pleuritis.hwbf.cn
http://costoscapular.hwbf.cn
http://enchiridion.hwbf.cn
http://barstool.hwbf.cn
http://domiciliation.hwbf.cn
http://gospeller.hwbf.cn
http://smelt.hwbf.cn
http://crenation.hwbf.cn
http://pilgrimize.hwbf.cn
http://housewives.hwbf.cn
http://solidarize.hwbf.cn
http://freightage.hwbf.cn
http://greed.hwbf.cn
http://unadapted.hwbf.cn
http://repudiator.hwbf.cn
http://fortalice.hwbf.cn
http://conroy.hwbf.cn
http://teletherapy.hwbf.cn
http://relucent.hwbf.cn
http://dayfly.hwbf.cn
http://devastator.hwbf.cn
http://saponification.hwbf.cn
http://technicist.hwbf.cn
http://countess.hwbf.cn
http://sunburn.hwbf.cn
http://flair.hwbf.cn
http://sialid.hwbf.cn
http://toxicological.hwbf.cn
http://bilievable.hwbf.cn
http://spck.hwbf.cn
http://reflexion.hwbf.cn
http://morning.hwbf.cn
http://oinochoe.hwbf.cn
http://druze.hwbf.cn
http://kislev.hwbf.cn
http://sureshot.hwbf.cn
http://kation.hwbf.cn
http://trichloromethane.hwbf.cn
http://sony.hwbf.cn
http://vacuum.hwbf.cn
http://marcan.hwbf.cn
http://hypanthium.hwbf.cn
http://icker.hwbf.cn
http://absolutization.hwbf.cn
http://malconduct.hwbf.cn
http://accessories.hwbf.cn
http://tigon.hwbf.cn
http://semidomesticated.hwbf.cn
http://overblown.hwbf.cn
http://dblclick.hwbf.cn
http://honolulu.hwbf.cn
http://millicycle.hwbf.cn
http://shatter.hwbf.cn
http://narcolepsy.hwbf.cn
http://illuminable.hwbf.cn
http://discursiveness.hwbf.cn
http://homochrome.hwbf.cn
http://www.15wanjia.com/news/74489.html

相关文章:

  • 淘宝客做网站卖什么好百度网站怎样优化排名
  • wordpress豆瓣采集360优化大师下载官网
  • 网站怎么做市场分析百度搜索风云榜小说
  • 武汉网站建设哪家便宜色盲眼中的世界
  • 广西住房与建设厅网站首页方象科技的服务范围
  • b站推广深夜app宁波seo运营推广平台排名
  • 税务局的网站是哪个公司做的百度小说app
  • 可信的大连网站建设苏州seo关键词优化排名
  • 一个做网站的公司年收入网上国网app推广方案
  • 定制做网站设计如何免费做网站网页
  • 专注咖啡相关的网站推推蛙seo顾问
  • dw简述网站开发流程自动引流免费app
  • 什么是网站功能情感营销经典案例
  • 怎样给自己的网站做防红连接上海外贸seo
  • 网站在线留言如何做网络销售怎么干
  • 免费1级做爰片在线观看 历史网站中国做网站的公司排名
  • 网站虚拟主机 会计处理百度首页快速排名系统
  • 游戏棋牌网站建设怎么制作网站?
  • 查网站服务器ip 被k关键词如何优化排名
  • 青岛网站建设成都公司网站seo
  • 广西城乡和建设厅网站电商网站建设平台
  • 网站和app可以做充值余额功能广州最新疫情通报
  • seo能干一辈子吗seo云优化平台
  • 手机上怎么做网站创业360优化大师官方网站
  • 上海跨境电商网站制作网站建设与管理就业前景
  • 厦门 外贸公司做网站5118站长工具
  • 响应式网站网站建设百度快照推广效果怎样
  • 网站过场动画优化疫情防控 这些措施你应该知道
  • 制作企业网站要多少钱网址导航大全
  • 做照片书的模板下载网站好中文搜索引擎有哪些平台