国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

營銷型單頁面網(wǎng)站制作百度電腦版下載

營銷型單頁面網(wǎng)站制作,百度電腦版下載,wordpress abspath,wordpress建設中插件前言: 在 Android 音頻系統(tǒng)中,AudioMixer 是音頻框架中一個關鍵的組件,用于處理多路音頻流的混音操作。它主要存在于音頻回放路徑中,是 AudioFlinger 服務的一部分。 上一節(jié)我們講threadloop的時候,提到了一個函數(shù)pr…

前言:

在 Android 音頻系統(tǒng)中,AudioMixer 是音頻框架中一個關鍵的組件,用于處理多路音頻流的混音操作。它主要存在于音頻回放路徑中,是 AudioFlinger 服務的一部分。

上一節(jié)我們講threadloop的時候,提到了一個函數(shù)prepareTracks_l,在這個函數(shù)的最后就調(diào)用了 mAudioMixer->create、mAudioMixer->setParameter去設置參數(shù),channel、format、volume等等。

AudioMixer繼承自 AudioMixerBase,當我們?nèi)タ碅udioMixer的構造函數(shù)的時候發(fā)現(xiàn)并沒有做任何操作
在這里插入圖片描述

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

走進AudioMixer:

我們看prepareTracks_l內(nèi)關于mAudioMixer的調(diào)用流程就可以發(fā)現(xiàn),他首先調(diào)用了create函數(shù),然而Audiomixer內(nèi)部卻沒有實現(xiàn)create接口,我們追溯到它的父類,發(fā)現(xiàn)在AudioMixerBase對象種定義了create接口并且實現(xiàn)了。

我們粗略的看下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的初始化。

初始化完成后就開始調(diào)用AudioMixer內(nèi)部的接口了,我們依次往下看發(fā)現(xiàn)還有getUnreleasedFrames、setParameter、setBufferProvider、process等。
我們先看下setParameter,當屬性變化的時候就會調(diào)用到這里。


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);}
}

函數(shù)的主要結構就是一個switch,首先通過trackId找到對應的track對象,然后去設置對應track的parameter參數(shù),例如 CHANNEL_MASK、FORMAT、MAIN_BUFFER等。

這只是設置參數(shù),那混音在哪里呢?我們繼續(xù)往下看process

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

這里主要就是調(diào)用mHook,mHook是一個函數(shù)指針,他會根據(jù)不同的場景分別調(diào)用不同的函數(shù)。

  • process__nop:初始值
  • process__genericResampling:對兩路以上的track進行重采樣操作
  • process__genericNoResampling:對兩路以上的track不進行重采樣操作
  • process__validate:這個函數(shù)就是根據(jù)當前的不同情況將mHook指向不同的函數(shù)
  • process__oneTrack16BitsStereoNoResampling:只有一路track,16bit,立體聲的時候不進行重采樣
process_hook_t mHook = &AudioMixerBase::process__nop;

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

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

process__validate是在invalidate函數(shù)里幅值給了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());}}}}}
}

這個函數(shù)首先使用while循環(huán)來遍歷每一個track,然后通過 NEEDS_RESAMPLE、NEEDS_AUX、NEEDS_CHANNEL_1、NEEDS_MUTE等判斷,最終得到resampling、all16BitsStereoNoResample、volumeRamp的值,然后基于這幾個值來決定調(diào)用,mHook來指向哪一個函數(shù)。

至于音頻流數(shù)據(jù)是如何混到一起的,我們后面章節(jié)再來進一步分析。

http://m.aloenet.com.cn/news/33674.html

相關文章:

  • 網(wǎng)站google排名出現(xiàn)過幾分鐘seo是什么意思 為什么要做seo
  • 坊網(wǎng)站建設seo和sem的概念
  • 自己電腦上做網(wǎng)站南寧百度快速優(yōu)化
  • 自媒體代運營怎么收費seo發(fā)外鏈的網(wǎng)站
  • 做網(wǎng)站的公司都有哪些崗位如何在手機上制作網(wǎng)站
  • 南寧市網(wǎng)站維護與推廣公司品牌的宣傳及推廣
  • 營銷型網(wǎng)站建設和規(guī)劃培訓班該如何建站
  • 淇縣網(wǎng)站建設谷歌下載
  • 上海網(wǎng)站開發(fā)公司外包臨沂做網(wǎng)站建設公司
  • wordpress js 頁腳seo經(jīng)驗是什么
  • 邢臺網(wǎng)站推廣費用seo權威入門教程
  • 做網(wǎng)站當生日禮物網(wǎng)絡營銷五個特點
  • 承德做網(wǎng)站優(yōu)化百度識圖鑒你所見
  • 網(wǎng)站開發(fā)怎么做常用的網(wǎng)絡營銷平臺有哪些
  • 茂名百度搜索網(wǎng)站排名青島網(wǎng)頁搜索排名提升
  • 收款網(wǎng)站怎么建設網(wǎng)絡營銷方案設計
  • 網(wǎng)頁制作公司網(wǎng)站網(wǎng)絡事件營銷案例
  • 陜西省建設網(wǎng)三類人員證書查詢正規(guī)網(wǎng)站優(yōu)化公司
  • 北京市文化局政務網(wǎng)站建設項目有沒有推廣app的平臺
  • wordpress 新聞采集站百度做廣告怎么做
  • 自己網(wǎng)站可以加標志嗎域名搜索引擎
  • 湖南手機版建站系統(tǒng)哪家好石家莊學院
  • 校園互動網(wǎng)站建設網(wǎng)絡營銷的宏觀環(huán)境
  • 本溪做網(wǎng)站的快優(yōu)吧seo優(yōu)化
  • 太原企業(yè)做網(wǎng)站營銷團隊找產(chǎn)品合作
  • 重慶門戶網(wǎng)站開發(fā)報價seo網(wǎng)站結構優(yōu)化的方法
  • 綿陽專門做網(wǎng)站的公司有哪些產(chǎn)品如何做線上推廣
  • 博客系統(tǒng)做網(wǎng)站aso搜索優(yōu)化
  • 做視頻網(wǎng)站視頻放在哪里找營銷型企業(yè)網(wǎng)站
  • html商品展示頁面專業(yè)搜索引擎seo技術公司