欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

android波形,android 波紋擴(kuò)散效果

Android Audio System 之一:AudioTrack如何與AudioFlinger交換

引子Android Framework的音頻子系統(tǒng)中,每一個音頻流對應(yīng)著一個AudioTrack類的一個實例,每個AudioTrack會在創(chuàng)建時注冊到 AudioFlinger中,由AudioFlinger把所有的AudioTrack進(jìn)行混合(Mixer),然后輸送到AudioHardware中 進(jìn)行播放,目前Android的Froyo版本設(shè)定了同時最多可以創(chuàng)建32個音頻流,也就是說,Mixer最多會同時處理32個AudioTrack的數(shù) 據(jù)流。如何使用AudioTrackAudioTrack的主要代碼位于 frameworks/base/media/libmedia/audiotrack.cpp中。現(xiàn)在先通過一個例子來了解一下如何使用 AudioTrack,ToneGenerator是android中產(chǎn)生電話撥號音和其他音調(diào)波形的一個實現(xiàn),我們就以它為例子:ToneGenerator的初始化函數(shù):bool ToneGenerator::initAudioTrack() { // Open audio track in mono, PCM 16bit//, default sampling rate, default buffer size mpAudioTrack = new AudioTrack(); mpAudioTrack-set(mStreamType, 0, AudioSystem::PCM_16_BIT, AudioSystem::CHANNEL_OUT_MONO, 0, 0, audioCallback, this, 0, 0, mThreadCanCallJava); if (mpAudioTrack-initCheck() != NO_ERROR) { LOGE("AudioTrack-initCheck failed"); goto initAudioTrack_exit; } mpAudioTrack-setVolume(mVolume, mVolume); mState = TONE_INIT; ...... } 可見,創(chuàng)建步驟很簡單,先new一個AudioTrack的實例,然后調(diào)用set成員函數(shù)完成參數(shù)的設(shè)置并注冊到AudioFlinger中,然后可以調(diào) 用其他諸如設(shè)置音量等函數(shù)進(jìn)一步設(shè)置音頻參數(shù)。其中,一個重要的參數(shù)是audioCallback,audioCallback是一個回調(diào)函數(shù),負(fù)責(zé)響應(yīng) AudioTrack的通知,例如填充數(shù)據(jù)、循環(huán)播放、播放位置觸發(fā)等等。回調(diào)函數(shù)的寫法通常像這樣:void ToneGenerator::audioCallback(int event, void* user, void *info) { if (event != AudioTrack::EVENT_MORE_DATA) return; AudioTrack::Buffer *buffer = static_castAudioTrack::Buffer *(info); ToneGenerator *lpToneGen = static_castToneGenerator *(user); short *lpOut = buffer-i16; unsigned int lNumSmp = buffer-size/sizeof(short); const ToneDescriptor *lpToneDesc = lpToneGen-mpToneDesc; if (buffer-size == 0) return; // Clear output buffer: WaveGenerator accumulates into lpOut buffer memset(lpOut, 0, buffer-size); ...... // 以下是產(chǎn)生音調(diào)數(shù)據(jù)的代碼,略.... } 該函數(shù)首先判斷事件的類型是否是EVENT_MORE_DATA,如果是,則后續(xù)的代碼會填充相應(yīng)的音頻數(shù)據(jù)后返回,當(dāng)然你可以處理其他事件,以下是可用的事件類型:enum event_type { EVENT_MORE_DATA = 0,// Request to write more data to PCM buffer. EVENT_UNDERRUN = 1,// PCM buffer underrun occured. EVENT_LOOP_END = 2,// Sample loop end was reached; playback restarted from loop start if loop count was not 0. EVENT_MARKER = 3,// Playback head is at the specified marker position (See setMarkerPosition()). EVENT_NEW_POS = 4,// Playback head is at a new position (See setPositionUpdatePeriod()). EVENT_BUFFER_END = 5// Playback head is at the end of the buffer. }; 開始播放:mpAudioTrack-start(); 停止播放:mpAudioTrack-stop(); 只要簡單地調(diào)用成員函數(shù)start()和stop()即可。AudioTrack和AudioFlinger的通信機(jī)制通常,AudioTrack和AudioFlinger并不在同一個進(jìn)程中,它們通過android中的binder機(jī)制建立聯(lián)系。AudioFlinger是android中的一個service,在android啟動時就已經(jīng)被加載。下面這張圖展示了他們兩個的關(guān)系:圖一AudioTrack和AudioFlinger的關(guān)系我們可以這樣理解這張圖的含義:audio_track_cblk_t實現(xiàn)了一個環(huán)形FIFO;AudioTrack是FIFO的數(shù)據(jù)生產(chǎn)者;AudioFlinger是FIFO的數(shù)據(jù)消費者。建立聯(lián)系的過程下面的序列圖展示了AudioTrack和AudioFlinger建立聯(lián)系的過程:圖二AudioTrack和AudioFlinger建立聯(lián)系解釋一下過程:Framework或者Java層通過JNI,new AudioTrack();根據(jù)StreamType等參數(shù),通過一系列的調(diào)用getOutput();如有必要,AudioFlinger根據(jù)StreamType打開不同硬件設(shè)備;AudioFlinger為該輸出設(shè)備創(chuàng)建混音線程: MixerThread(),并把該線程的id作為getOutput()的返回值返回給AudioTrack;AudioTrack通過binder機(jī)制調(diào)用AudioFlinger的createTrack();AudioFlinger注冊該AudioTrack到MixerThread中;AudioFlinger創(chuàng)建一個用于控制的TrackHandle,并以IAudioTrack這一接口作為createTrack()的返回值;AudioTrack通過IAudioTrack接口,得到在AudioFlinger中創(chuàng)建的FIFO(audio_track_cblk_t);AudioTrack創(chuàng)建自己的監(jiān)控線程:AudioTrackThread;自此,AudioTrack建立了和AudioFlinger的全部聯(lián)系工作,接下來,AudioTrack可以:通過IAudioTrack接口控制該音軌的狀態(tài),例如start,stop,pause等等;通過對FIFO的寫入,實現(xiàn)連續(xù)的音頻播放;監(jiān)控線程監(jiān)控事件的發(fā)生,并通過audioCallback回調(diào)函數(shù)與用戶程序進(jìn)行交互;FIFO的管理 audio_track_cblk_taudio_track_cblk_t這個結(jié)構(gòu)是FIFO實現(xiàn)的關(guān)鍵,該結(jié)構(gòu)是在createTrack的時候,由AudioFlinger申請相 應(yīng)的內(nèi)存,然后通過IMemory接口返回AudioTrack的,這樣AudioTrack和AudioFlinger管理著同一個 audio_track_cblk_t,通過它實現(xiàn)了環(huán)形FIFO,AudioTrack向FIFO中寫入音頻數(shù)據(jù),AudioFlinger從FIFO 中讀取音頻數(shù)據(jù),經(jīng)Mixer后送給AudioHardware進(jìn)行播放。audio_track_cblk_t的主要數(shù)據(jù)成員: user -- AudioTrack當(dāng)前的寫位置的偏移 userBase -- AudioTrack寫偏移的基準(zhǔn)位置,結(jié)合user的值方可確定真實的FIFO地址指針 server -- AudioFlinger當(dāng)前的讀位置的偏移 serverBase -- AudioFlinger讀偏移的基準(zhǔn)位置,結(jié)合server的值方可確定真實的FIFO地址指針 frameCount -- FIFO的大小,以音頻數(shù)據(jù)的幀為單位,16bit的音頻每幀的大小是2字節(jié) buffers -- 指向FIFO的起始地址 out -- 音頻流的方向,對于AudioTrack,out=1,對于AudioRecord,out=0audio_track_cblk_t的主要成員函數(shù):framesAvailable_l()和framesAvailable()用于獲取FIFO中可寫的空閑空間的大小,只是加鎖和不加鎖的區(qū)別。uint32_t audio_track_cblk_t::framesAvailable_l() { uint32_t u = this-user; uint32_t s = this-server; if (out) { uint32_t limit = (s loopStart) ? s : loopStart; return limit + frameCount - u; } else { return frameCount + u - s; } } framesReady()用于獲取FIFO中可讀取的空間大小。uint32_t audio_track_cblk_t::framesReady() { uint32_t u = this-user; uint32_t s = this-server; if (out) { if (u loopEnd) { return u - s; } else { Mutex::Autolock _l(lock); if (loopCount = 0) { return (loopEnd - loopStart)*loopCount + u - s; } else { return UINT_MAX; } } } else { return s - u; } } 我們看看下面的示意圖: _____________________________________________ ^ ^ ^ ^ buffer_start server(s) user(u) buffer_end 很明顯,frameReady = u - s,frameAvalible = frameCount - frameReady = frameCount - u + s 可能有人會問,應(yīng)為這是一個環(huán)形的buffer,一旦user越過了buffer_end以后,應(yīng)該會發(fā)生下面的情況: _____________________________________________ ^ ^ ^ ^ buffer_start user(u) server(s) buffer_end這時候u在s的前面,用上面的公式計算就會錯誤,但是android使用了一些技巧,保證了上述公式一直成立。我們先看完下面三個函數(shù)的代碼再分析:uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) { uint32_t u = this-user; u += frameCount; ...... if (u = userBase + this-frameCount) { userBase += this-frameCount; } this-user = u; ...... return u; } bool audio_track_cblk_t::stepServer(uint32_t frameCount) { // the code below simulates lock-with-timeout // we MUST do this to protect the AudioFlinger server // as this lock is shared with the client. status_t err; err = lock.tryLock(); if (err == -EBUSY) { // just wait a bit usleep(1000); err = lock.tryLock(); } if (err != NO_ERROR) { // probably, the client just died. return false; } uint32_t s = this-server; s += frameCount; // 省略部分代碼 // ...... if (s = serverBase + this-frameCount) { serverBase += this-frameCount; } this-server = s; cv.signal(); lock.unlock(); return true; } void* audio_track_cblk_t::buffer(uint32_t offset) const { return (int8_t *)this-buffers + (offset - userBase) * this-frameSize; } stepUser()和stepServer的作用是調(diào)整當(dāng)前偏移的位置,可以看到,他們僅僅是把成員變量user或server的值加上需要移動 的數(shù)量,user和server的值并不考慮FIFO的邊界問題,隨著數(shù)據(jù)的不停寫入和讀出,user和server的值不斷增加,只要處理得 當(dāng),user總是出現(xiàn)在server的后面,因此frameAvalible()和frameReady()中的算法才會一直成立。根據(jù)這種算 法,user和server的值都可能大于FIFO的大小:framCount,那么,如何確定真正的寫指針的位置呢?這里需要用到userBase這一 成員變量,在stepUser()中,每當(dāng)user的值越過(userBase+frameCount),userBase就會增加 frameCount,這樣,映射到FIFO中的偏移總是可以通過(user-userBase)獲得。因此,獲得當(dāng)前FIFO的寫地址指針可以通過成員 函數(shù)buffer()返回:p = mClbk-buffer(mclbk-user);在AudioTrack中,封裝了兩個函數(shù):obtainBuffer()和releaseBuffer()操作 FIFO,obtainBuffer()獲得當(dāng)前可寫的數(shù)量和寫指針的位置,releaseBuffer()則在寫入數(shù)據(jù)后被調(diào)用,它其實就是簡單地調(diào)用 stepUser()來調(diào)整偏移的位置。IMemory接口在createTrack的過程中,AudioFlinger會根據(jù)傳入的frameCount參數(shù),申請一塊內(nèi)存,AudioTrack可以通過 IAudioTrack接口的getCblk()函數(shù)獲得指向該內(nèi)存塊的IMemory接口,然后AudioTrack通過該IMemory接口的 pointer()函數(shù)獲得指向該內(nèi)存塊的指針,這塊內(nèi)存的開始部分就是audio_track_cblk_t結(jié)構(gòu),緊接著是大小為frameSize的 FIFO內(nèi)存。IMemory-pointer() ----|_______________________________________________________ |__audio_track_cblk_t__|_______buffer of FIFO(size==frameCount)____|看看AudioTrack的createTrack()的代碼就明白了:spIAudioTrack track = audioFlinger-createTrack(getpid(), streamType, sampleRate, format, channelCount, frameCount, ((uint16_t)flags) 16, sharedBuffer, output, status); // 得到IMemory接口 spIMemory cblk = track-getCblk(); mAudioTrack.clear(); mAudioTrack = track; mCblkMemory.clear(); mCblkMemory = cblk; // 得到audio_track_cblk_t結(jié)構(gòu) mCblk = static_castaudio_track_cblk_t*(cblk-pointer()); // 該FIFO用于輸出 mCblk-out = 1; // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk-frameCount; if (sharedBuffer == 0) { // 給FIFO的起始地址賦值 mCblk-buffers = (char*)mCblk + sizeof(audio_track_cblk_t); } else { .......... } (DroidPhone)

創(chuàng)新互聯(lián)專注于青原網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供青原營銷型網(wǎng)站建設(shè),青原網(wǎng)站制作、青原網(wǎng)頁設(shè)計、青原網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造青原網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供青原網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

android media i2s怎么走

media的意思是媒體。媒體文件要用媒體播放器來播放。

WAV文件記錄的是聲音的波形,自然界的任何一種聲音都可以作為WAV文件來保存,而MID文件內(nèi)保存的是一些音樂符號,就像樂譜(如五線譜、簡譜)一樣,所以播放出來的只有音樂。

單擊【開始】按鈕,在開始菜單中單擊Windows?Media?Player命令,屏幕上彈出Windows?Media?Player窗口。

單擊【文件】菜單的【打開】命令,在彈出的【打開】對話框中,選擇要播放的多媒體文件并雙擊,開始播放選中的音樂文件,在播放控制區(qū)域中,顯示出當(dāng)前正在播放的文件進(jìn)度。

android 怎么繪制時時音頻波形圖

安卓開發(fā)音頻mic口接收20khz的波形的方法? 一、手機(jī)音頻通信的特點 1、 通用性強(qiáng):在智能手機(jī)普及的今天,手機(jī)的對外通信接口多種多樣,而其中以3.5mm的音頻接口通用新最強(qiáng),基本所有的手機(jī)、平板電腦都會有這個接口,所以在一些要求通用性的設(shè)...

有沒有可以在安卓手機(jī)上自制音樂而且免費操作又簡單的軟件?

Apple

GarageBand

適用設(shè)備:iPhone,iPod

touch,iPad(iOS4.3以上)

移動版本和Mac版本的功能類似,可以和Mac版同步,但是也有獨特之處。它配備了觸摸型智能樂器、八音軌音序器還有一組電吉他音箱和模擬效果器的經(jīng)典組合。

它的多樣化選項足可以讓你做一場精彩表演,不過唯一不能滿足你的就是無法編輯midi音效。

盡管這樣,iPad版GarageBand仍然是個推薦產(chǎn)品,它帶鍵盤接口,堪稱一款強(qiáng)大的速創(chuàng)作工具。而且它竟然是免費的。

拓展資料:

Flex

Time

和音樂套路匹配

音樂套路匹配是兩項強(qiáng)大的工具,可幫你改進(jìn)錄音中的節(jié)奏和樂感。你可以修正單個音符的時點,讓軌道的旋律更加緊湊,或輕松制作動聽的歌曲。

Flex

Time

是一項全新的工具,可讓你快速改變錄音的時點,讓歌曲擁有完美節(jié)奏。有些部分的演奏不在節(jié)點上?使用

Flex

Time

可快速修正時間錯誤。只需點擊并拖動波形圖的任意部分,就能修改一個音符或節(jié)拍的時點。你可移動、拉伸或縮短單個的音符,卻不會影響錄音的其他部分。Flex

Time

還能激發(fā)你的創(chuàng)意靈感:通過延長吉他即興演奏、修改人聲演唱、嘗試不同的節(jié)奏,然后獲得新的想法。用

Flex

Time

進(jìn)行的改動均會突出顯示,讓你可以輕松查看。你可隨時點擊

Flex

Time

按鈕,將你的修改與原始錄音進(jìn)行對比。

如果你正在處理多個不同的軌道,如吉他、貝斯、鍵盤、打擊樂器,還有最底層的鼓循環(huán)片段。那么,很可能其中一個(或全部)軌道的節(jié)奏會有所偏差。音樂套路匹配能讓所有軌道的節(jié)奏和諧統(tǒng)一。只需選定歌曲中的任意一條軌道,將它作為音樂套路軌道,其他所有軌道即可迅速與其匹配。如果不是每條軌道都需要調(diào)整,你可只選擇需要改動的軌道。音樂套路匹配還能讓Apple

如何復(fù)制Android的AudioSource.MIC

復(fù)制Audio Source可以用Cool Edit Pro。

Cool Edit Pro是一個非常出色的數(shù)字音頻編輯器,它能播放和錄制多種文件格式的音頻文件,并可以編輯合成文件并進(jìn)行幾種文件格式的轉(zhuǎn)換。同它的上一個版本Cool

Edit 96相比,它不僅保留了Cool Edit 96的眾多優(yōu)點,而且大大提高了處理速度和軟件功能。更讓人驚訝的是,Cool Edit Pro還攜帶了一個相當(dāng)專業(yè)且高效的音頻處理工具——多軌編輯器。總而言之,對于喜愛編輯制作電腦音樂的朋友來說,Cool Edit Pro擁有的數(shù)碼錄音、專業(yè)編輯等強(qiáng)大功能絕對會讓你興奮不已。

Cool Edit Pro對系統(tǒng)硬件的要求可高可低,主要看你打算如何使用了。如果只準(zhǔn)備用Cool Edit Pro制作一些簡單的特殊音效或用于MIDI的輔助編曲工作,那么就只需要Windows XP、486以上、8MB內(nèi)存、6MB可用硬盤空間就可以了。如果你想完全感受Cool Edit Pro的強(qiáng)大功能,從事復(fù)雜的硬盤錄音和編輯操作,從事復(fù)雜的硬盤錄音或編輯操作,就必須要586以上,16MB內(nèi)存。

Cool Edit Pro的工作界面絕對令你耳目一新,可顯示聲音波形的窗口上下密密麻麻地布滿了功能按鈕,一副專業(yè)錄音編輯臺的架勢。Cool Edit Pro界面又根據(jù)用戶需要,分為波形編輯界面和多音軌編輯界面兩個部分。

波形編輯界面主要用來對音軌文件進(jìn)行播放、分析、編輯處理和文件格式轉(zhuǎn)換。在播放音軌文件時,可以在波形窗口中觀察單個波形的實時數(shù)字信號處理效果,并可截獲其中某一段波形進(jìn)行編輯處理。波形編輯界面主要由標(biāo)題欄、菜單欄、工具欄、波形顯示區(qū)、波形縮放欄、CD播放控制以及狀態(tài)欄組成。

多音軌編輯界面與波形編輯界面相近,不同的是界面上的波形顯示區(qū)被劃分為四個區(qū)域。這四個區(qū)域可以同時用來實時檢測聲音文件中幾個音軌的播放效果,如吉他、鼓聲等等,并且可以對每個音軌進(jìn)行音量、均衡、靜音等編輯,然后再重新合成。波形顯示區(qū)左側(cè)分別對應(yīng)每個音軌控制臺,在音軌控制臺上可以顯示音軌名稱、音量、錄音/回放設(shè)備選擇,還可以對指定音軌進(jìn)行靜音、錄音等操作。

Cool Edit Pro播放聲音文件的方法十分簡單,單擊工具欄上的Open an existing waveform按鈕,在彈出的對話框中選擇要播放的音頻文件,然后單擊工具欄上的Play按鈕即可播放這個音頻文件。在播放音頻文件時,波形顯示區(qū)中將會實時顯示波形播放效果。如果要對其中一段音樂進(jìn)行編輯,可以用鼠標(biāo)直接在波形顯示區(qū)選擇這段波形,然后使用剪貼工具把它復(fù)制到剪貼板上。還可以把這段波形粘貼到另一個位置,也可以使用工具對它進(jìn)行縮放調(diào)整,然后再粘貼。

使用Cool Edit Pro轉(zhuǎn)換文件格式也十分簡單方便,只要在File菜單中單擊Save as命令,打開Save as對話框,選擇需要的文件格式保存即可。

網(wǎng)頁題目:android波形,android 波紋擴(kuò)散效果
本文來源:http://chinadenli.net/article33/dsspcss.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)品牌網(wǎng)站設(shè)計網(wǎng)站建設(shè)手機(jī)網(wǎng)站建設(shè)網(wǎng)站內(nèi)鏈Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)