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

怎么在国际网站做推广网络营销推广策略有哪些

怎么在国际网站做推广,网络营销推广策略有哪些,vs2010网站建设,网站建设首选公司在 Android 平台上,音频混合器 AudioMixer 主要用在 AudioFlinger 里,将多路音频源数据混音(包括混音、音量处理、重采样及处理声道等)。位于 framework 的音频处理模库 libaudioprocessing(frameworks/av/media/libau…

在 Android 平台上,音频混合器 AudioMixer 主要用在 AudioFlinger 里,将多路音频源数据混音(包括混音、音量处理、重采样及处理声道等)。位于 framework 的音频处理模库 libaudioprocessing(frameworks/av/media/libaudioprocessing)中。

一、音频混合器

混音器(AudioMixer)是在混音回放线程类(MixerThread)中的构造函数内创建。

1、混合器创建

源码位置:/frameworks/av/services/audioflinger/Threads.cpp

AudioFlinger::MixerThread::MixerThread(……) 
{……// 往hal层一次写数据的大小。hal层设备的采样率。mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);……
}

这说明了一个 MixerThread 对应一个 AudioMixer,而且 MixerThread 传了两个参数给AudioMixer:
mNormalFrameCount:一次输送数据的长度,把源 buffer 的音频数据写入目的 buffer。
mSampleRate:音频数据输出的采样率。

2、功能接口

AudioMixer源码位置:/frameworks/av/media/libaudioprocessing/AudioMixer.cpp

void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider)

此方法允许用户根据给定的索引设置一个音频缓冲区提供者,name 作为索引,bufferProvider由 mActiveTracks 取出来的 Track 对象提供。这样audiomixer混音时就从track对应的IFFO取数据。

void AudioMixer::setParameter(int name, int target, int param, void *value)

该函数主要用于设置特定参数值,涉及到了音频处理中多种参数的设置,包括通道掩码、缓冲区指针、格式、重采样、音量衰减、时间拉伸等。

这里我们主要看一下 target 和 param 的不同参数所对应实现的相关功能:

在这里插入图片描述
标注基类是直接透传调用 AudioMixerBase.cpp 中的对应函数。AudioMixer 继承自 AudioMixerBase,同时基类中也有几个比较重要的函数。这里我们需要关注的是参数MAIN_BUFFER。audiomixer会将从track获取的FIFO数据和MAIN_BUFFER混音后存入MAIN_BUFFER。

AudioMixerBase

源码位置:/frameworks/av/media/libaudioprocessing/AudioMixerBase.cpp

// 启用指定的音频轨道
void AudioMixerBase::enable(int name)
// 禁用指定的音频轨道
void AudioMixerBase::disable(int name)
// 销毁指定的音频轨道
void AudioMixerBase::destroy(int name)

这几个函数主要是用于音频轨道的控制功能,确保了轨道能够在不同状态下正确工作。

刷新函数

上面的接口中大量调用 invalidate() 函数,该函数的主要作用就是刷新 Track。源码位置:/frameworks/av/media/libaudioprocessing/include/media/AudioMixerBase.h

// 当轨道信息改变,需要确定一个新的进程钩子时调用下面的函数
void invalidate() {mHook = &AudioMixerBase::process__validate;
}

可以看到该函数用于当轨道信息发生变化时,重新确定一个新的进程钩子。这个钩子通常用于验证和处理轨道信息的变化,调用 AudioMixerBase 中的 process__validate() 函数。

void AudioMixerBase::process__validate()
{……// 遍历轨道for (const auto &pair : mTracks) {const int name = pair.first;const std::shared_ptr<TrackBase> &t = pair.second;// 判断该track是否需要混音if (!t->enabled) continue;// 将启用的轨道添加到 mEnabled 和 mGroups 中mEnabled.emplace_back(name);mGroups[t->mainBuffer].emplace_back(name);// 计算每个轨道的需求 (needs) 并设置相应的处理钩子 (hook)uint32_t n = 0;// 可以溢出(掩码只有3位)n |= NEEDS_CHANNEL_1 + t->channelCount - 1;// 设置重采样 NEEDS_RESAMPLE 标志位if (t->doesResample()) {n |= NEEDS_RESAMPLE;}// 设置辅助通道 NEEDS_AUX 标志位if (t->auxLevel != 0 && t->auxBuffer != NULL) {n |= NEEDS_AUX;}if (t->volumeInc[0]|t->volumeInc[1]) {// 增益正在变化volumeRamp = true;} else if (!t->doesResample() && t->volumeRL == 0) {// 不需要重采样且增益为零n |= NEEDS_MUTE;}// 将所有设置好的标志位保存到 t->needs 中t->needs = n;if (n & NEEDS_MUTE) { // 需要静音t->hook = &TrackBase::track__nop;} else {if (n & NEEDS_AUX) { // 处理辅助通道all16BitsStereoNoResample = false;}if (n & NEEDS_RESAMPLE) { // 处理重采样all16BitsStereoNoResample = false;resampling = true;if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1&& t->channelMask == AUDIO_CHANNEL_OUT_MONO // MONO_HACK&& isAudioChannelPositionMask(t->mMixerChannelMask)) { // 重采样单声道t->hook = TrackBase::getTrackHook(TRACKTYPE_RESAMPLEMONO, t->mMixerChannelCount,t->mMixerInFormat, t->mMixerFormat);} else if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2&& t->useStereoVolume()) { // 重采样立体声t->hook = TrackBase::getTrackHook(TRACKTYPE_RESAMPLESTEREO, t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat);} else { // 其他情况t->hook = TrackBase::getTrackHook(TRACKTYPE_RESAMPLE, t->mMixerChannelCount,t->mMixerInFormat, t->mMixerFormat);}ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,"Track %d needs downmix + resample", name);} else { // 处理无需重采样的情况……}}}// 根据条件选择合适的处理钩子mHook = &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 {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) {mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK, t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat, t->useStereoVolume());}}}}}……process();// 处理音量渐变,设置最优状态和轨道处理钩子if (mEnabled.size() > 0) {bool allMuted = true;for (const int name : mEnabled) {const std::shared_ptr<TrackBase> &t = mTracks[name];if (!t->doesResample() && t->volumeRL == 0) {t->needs |= NEEDS_MUTE;t->hook = &TrackBase::track__nop;} else {allMuted = false;}}if (allMuted) {mHook = &AudioMixerBase::process__nop;} else if (all16BitsStereoNoResample) {if (mEnabled.size() == 1) {const std::shared_ptr<TrackBase> &t = mTracks[mEnabled[0]];mHook = getProcessHook(PROCESSTYPE_NORESAMPLEONETRACK, t->mMixerChannelCount, t->mMixerInFormat, t->mMixerFormat, t->useStereoVolume());}}}
}

这些步骤确保了音频轨道信息变化时能够正确选择合理的钩子函数处理各种情况,包括重采样、音量渐变等。

二、AudioMixer混音

  关于混音,我们已经知道:混音以 track 为源,mainBuffer 为目标,frameCount 为一次混音长度。AudioMixer 最多能维护 32 个 track。track 可以对应不同 mainBuffer,尽管一般情况下他们的 mainBuffer 都是同一个。

在这里插入图片描述

调用 AudioMixer 的 process 方法进行混音的,实际上混音的方法是调用 AudioMixerBase 内的 process_xxx 方法,各个 process 方法大同小异。下面来分析 process__genericResampling 这个方法。
1、AudioMixerBase.cppp
rocess__genericResampling

void AudioMixerBase::process__genericResampling()
{ALOGVV("process__genericResampling\n");// 初始化 outTemp 指针int32_t * const outTemp = mOutputTemp.get(); // 获取当前帧数 numFramessize_t numFrames = mFrameCount;// 遍历每个音频组 mGroupsfor (const auto &pair : mGroups) {const auto &group = pair.second;// 获取第一个轨道 t1const std::shared_ptr<TrackBase> &t1 = mTracks[group[0]];// 清除了临时缓冲区 outTempmemset(outTemp, 0, sizeof(*outTemp) * t1->mMixerChannelCount * mFrameCount);// 处理每个轨道for (const int name : group) {const std::shared_ptr<TrackBase> &t = mTracks[name];int32_t *aux = NULL;if (CC_UNLIKELY(t->needs & NEEDS_AUX)) {aux = t->auxBuffer;}// 如果轨道需要重采样,则直接调用重采样钩子if (t->needs & NEEDS_RESAMPLE) {(t.get()->*t->hook)(outTemp, numFrames, mResampleTemp.get() /* naked ptr */, aux);} else { // 逐帧获取数据并调用处理钩子// 清除临时缓冲区size_t outFrames = 0;// 获取每个轨道的数据并调用相应的处理钩子while (outFrames < numFrames) {t->buffer.frameCount = numFrames - outFrames;t->bufferProvider->getNextBuffer(&t->buffer);t->mIn = t->buffer.raw;// t->mIn == nullptr:启用混音后刚刚刷新音轨if (t->mIn == nullptr) break;(t.get()->*t->hook)(outTemp + outFrames * t->mMixerChannelCount, t->buffer.frameCount,mResampleTemp.get() /* naked ptr */, aux != nullptr ? aux + outFrames : nullptr);outFrames += t->buffer.frameCount;t->bufferProvider->releaseBuffer(&t->buffer);}}}// 将处理后的数据转换为混音器所需的格式convertMixerFormat(t1->mainBuffer, t1->mMixerFormat,outTemp, t1->mMixerInFormat, numFrames * t1->mMixerChannelCount);}
}

这些步骤确保了在需要重采样的情况下,能够正确处理每个轨道的数据,并将其转换为所需的格式。

http://www.dtcms.com/wzjs/332788.html

相关文章:

  • 新手学做百度联盟网站seo搜索优化公司排名
  • html电影网站源码中国时事新闻网
  • 铁岭做网站公司哪家好网址如何下载视频
  • 北京公司注册最新政策武汉网站营销seo方案
  • 网站建设论文基础摘要计算机培训班
  • 有什么做兼职的可靠的网站市场监督管理局职责
  • 网站建设职业培训北京网站制作建设公司
  • wordpress 印象码谷歌seo网站排名优化
  • 景宁县建设局网站百度网盘搜索引擎官方入口
  • 网站备案怎么注销广告推广公司
  • 某个网站做拍卖预展的好处在线识别图片
  • 企业展厅方案seo引擎优化方案
  • 做网站到底要不要备案什么文案容易上热门
  • 网站建设是怎么赚钱的东莞推广服务
  • 网站建设怎么寻找客户东莞seo外包公司
  • 网站域名的管理密码如何索取文章代写
  • ios开发者测试版seo 怎么做到百度首页
  • vr全景网站开发制作最近新闻热点事件
  • 图片展示型网站模板关键帧
  • 做门户网站的意义在哪seo中文含义
  • 网站建设毕业设计提问百度爱采购
  • 电脑游戏网站建设电商运营转行后悔了
  • 上海网站建设网站游戏温州免费建站模板
  • 网站友情链接要加什么软文是什么意思
  • 襄阳营销型网站建设搜索引擎网址
  • 顺德网站建设多少钱近期的新闻消息
  • 古交网站建设推广百度数据
  • 上海低价网站建设sem是什么意思?
  • 体育网站建设需求陕西今日头条新闻
  • 做高端网站的公司百度小说搜索风云榜排名