【導(dǎo)讀】音頻信號(hào)處理產(chǎn)品的設(shè)計(jì)和編碼軟件有其獨(dú)特的挑戰(zhàn)。那么,開(kāi)發(fā)人員最常犯的錯(cuò)誤是什么?如何避免這些錯(cuò)誤呢?
無(wú)論最終產(chǎn)品是什么,無(wú)論他們使用什么語(yǔ)言編寫(xiě)代碼,世界各地的軟件開(kāi)發(fā)人員都面臨著同樣的挑戰(zhàn)——不斷變化的客戶(hù)需求、緊迫的交期、整合和客戶(hù)支持,以上只是幾個(gè)例子。
但是有一種類(lèi)型的軟件開(kāi)發(fā)涉及了解和解決非常具體的問(wèn)題。音頻信號(hào)處理產(chǎn)品的設(shè)計(jì)和編碼軟件有其獨(dú)特的挑戰(zhàn)。那么,開(kāi)發(fā)人員最常犯的錯(cuò)誤是什么?如何避免這些錯(cuò)誤呢?
了解信號(hào)處理對(duì)于在音頻領(lǐng)域工作的軟件工程師很有幫助,但這不是必需的。然而,有些領(lǐng)域?qū)σ纛l有一些了解確實(shí)有所幫助。
首先,是增益結(jié)構(gòu),了解音量控制可以為我們的系統(tǒng)增加增益。這適用于我們軟件的內(nèi)部結(jié)構(gòu),并將影響我們插入原型的所有小工具。結(jié)果可能是聲音輸出令人不滿意。開(kāi)發(fā)人員以為這是由于代碼中的錯(cuò)誤造成的,而實(shí)際上這是增益結(jié)構(gòu)的問(wèn)題。知道這一點(diǎn)可以在不必要的調(diào)試中節(jié)省大量時(shí)間。
其次,軟件開(kāi)發(fā)人員有時(shí)會(huì)忘記音頻濾波會(huì)增加群延遲。如果我們忘記了這個(gè)基本事實(shí),我們可能會(huì)過(guò)分承諾我們的算法的性能,我們會(huì)認(rèn)為它會(huì)比實(shí)際行動(dòng)得更快。
第三,一個(gè)雖然很小但很重要的點(diǎn)是實(shí)際數(shù)據(jù)和理論數(shù)據(jù)之間的差異。數(shù)學(xué)有零,但音頻沒(méi)有。在數(shù)學(xué)中,算法的設(shè)計(jì)使用理論數(shù)據(jù)。當(dāng)使用實(shí)際數(shù)據(jù)測(cè)試我們的系統(tǒng)時(shí),我們可能會(huì)發(fā)現(xiàn)一個(gè)信號(hào)似乎是無(wú)聲的。在那種情況下,放大它總是值得的——它可能有點(diǎn)嘶嘶聲,也可能全是零。
最后,我們不可能只采用一種算法并將其部署在所有設(shè)備上。我們需要在開(kāi)發(fā)過(guò)程中盡早考慮我們的算法將要有的部署約束條件。一些DSP非常高效且功耗低,但它們的內(nèi)存可能有限。其他的可能非常適合用于AI處理,但它們會(huì)引入更高的延遲。如果你能設(shè)計(jì)一個(gè)權(quán)衡空間和時(shí)間的算法,那就太好了。但實(shí)際上,大多數(shù)算法無(wú)法做到這一點(diǎn),因此我們可能會(huì)發(fā)現(xiàn)自己無(wú)法獲得功耗最低的嵌入式設(shè)備。
在任何開(kāi)發(fā)中,在開(kāi)發(fā)開(kāi)始之前了解客戶(hù)需求是必不可少的。但在處理音頻時(shí),這一點(diǎn)更為重要。為什么呢?因?yàn)閷?duì)于音頻,客戶(hù)不僅需要一個(gè)運(yùn)行良好的系統(tǒng),他們還需要一個(gè)可以輸出出色音頻的系統(tǒng)。問(wèn)題是每個(gè)人聽(tīng)到的聲音都不一樣(例如,年齡會(huì)影響聽(tīng)力敏銳度),而且我們對(duì)聽(tīng)起來(lái)“好”的聲音都有個(gè)人偏好。我們可能會(huì)發(fā)現(xiàn)我們花了很長(zhǎng)時(shí)間開(kāi)發(fā)的一種產(chǎn)品,最終客戶(hù)根本不喜歡。
對(duì)于大多數(shù)音頻開(kāi)發(fā)人員來(lái)說(shuō),這是一個(gè)持續(xù)存在的問(wèn)題。音頻的評(píng)估比視覺(jué)算法的評(píng)估更難。這是為什么?因?yàn)橐曈X(jué)結(jié)果可以并排放置并同時(shí)將它們相互進(jìn)行比較。但你不能同時(shí)比較音頻:你不能同時(shí)聽(tīng)兩件事。因此,音頻結(jié)果的A/B測(cè)試只能是順序的,不能同時(shí)進(jìn)行。所以,測(cè)試音頻需要更長(zhǎng)的時(shí)間,我們可能需要聽(tīng)兩個(gè)小時(shí)的測(cè)試錄音僅僅是為了評(píng)估對(duì)算法的小調(diào)整。我們要確保項(xiàng)目的計(jì)劃包含有比我們認(rèn)為需要的更長(zhǎng)的測(cè)試時(shí)間。
我們可以通過(guò)商定使用一種普遍被接受的音頻測(cè)試指標(biāo)(例如MOS分?jǐn)?shù))來(lái)避免這種主觀性。這些輸入的音頻和預(yù)期所需的觀眾對(duì)結(jié)果的評(píng)價(jià)。確實(shí)有助于評(píng)估質(zhì)量,但不會(huì)給我們提供改進(jìn)的原因。許多常見(jiàn)的測(cè)試和指標(biāo)是為有線電話等傳統(tǒng)的現(xiàn)有應(yīng)用開(kāi)發(fā)的,并且偏向于這些應(yīng)用。因此,使用指標(biāo)會(huì)有所幫助,但這不是絕對(duì)的答案。在我們開(kāi)始工作之前,要確保我們的客戶(hù)把他們的愿景告訴我們,因?yàn)樗麄兿M纛l聽(tīng)起來(lái)像什么,這一點(diǎn)至關(guān)重要。
了解客戶(hù)的愿景對(duì)于下一個(gè)要注意的問(wèn)題整合也很重要。我們的音頻是系統(tǒng)的一部分。所有部分都必須協(xié)同工作,但系統(tǒng)的其余部分受處理音頻的消耗限制,而我們的音頻也受系統(tǒng)其余部分消耗的限制。如果音頻在實(shí)際的系統(tǒng)上斷斷續(xù)續(xù),那么在空的系統(tǒng)上開(kāi)發(fā)運(yùn)行良好的東西是沒(méi)有意義的,而且會(huì)浪費(fèi)很多資源。所以,早點(diǎn)整合吧。但是,正如開(kāi)發(fā)人員都知道的,整合的成本很高。為了防止將時(shí)間浪費(fèi)在整合不合適的內(nèi)容上,我們首先需要與客戶(hù)交談。并且,在開(kāi)始開(kāi)發(fā)之前,獲取所選用例中的一些錄音樣本,同時(shí)預(yù)覽它們或離線工作來(lái)估計(jì)我們將能夠?qū)崿F(xiàn)的目標(biāo)并確保它符合客戶(hù)的愿景。
開(kāi)發(fā)人員會(huì)犯的一個(gè)常見(jiàn)錯(cuò)誤是在開(kāi)發(fā)過(guò)程中沒(méi)有盡早獲得軟件流。這很重要,因?yàn)槿绻覀儾槐M早進(jìn)行流式傳輸,我們可能會(huì)要處理導(dǎo)致結(jié)果過(guò)分承諾的文件。如果我們正在編寫(xiě)一種算法,它每訪問(wèn)一位音頻就向數(shù)據(jù)結(jié)構(gòu)添加一個(gè)成分,則數(shù)據(jù)結(jié)構(gòu)的大小與我們正在處理的文件的大小成正比。然而,一旦文件被音頻流替換,數(shù)據(jù)結(jié)構(gòu)可能會(huì)在設(shè)備運(yùn)行時(shí)無(wú)限增大。通過(guò)盡早流式傳輸,可以降低開(kāi)發(fā)風(fēng)險(xiǎn),并且可以進(jìn)一步確保我們的算法已準(zhǔn)備好進(jìn)行大規(guī)模生產(chǎn)。
另外,從一開(kāi)始就考慮測(cè)試過(guò)程。僅通過(guò)音頻輸出進(jìn)行測(cè)試很困難,因?yàn)樗菍?shí)數(shù)信號(hào)。要確保盡可能多地進(jìn)行單元測(cè)試,而不是依賴(lài)于不同處理器和平臺(tái)之間可能不同的音頻輸出。
查看編碼過(guò)程本身,我們需要在定點(diǎn)和浮點(diǎn)之間做出決定。定點(diǎn)曾經(jīng)是表示用于存儲(chǔ)和計(jì)算的音頻樣本的“go to”方法。定點(diǎn)計(jì)算將使用與整數(shù)計(jì)算相同的ALU部件,一個(gè)簡(jiǎn)單的數(shù)學(xué)技巧是大致估計(jì)連續(xù)變化的數(shù)量,在精度和數(shù)量大小之間進(jìn)行權(quán)衡。
浮點(diǎn)在ALU中實(shí)現(xiàn)起來(lái)更復(fù)雜,但在現(xiàn)代CPU中(例如在移動(dòng)設(shè)備中)使用它幾乎沒(méi)有或完全沒(méi)有損失。存在的損失被工程時(shí)間要求的減少和用于優(yōu)化算法的時(shí)間量的增加所抵消。音頻算法通常龐大而復(fù)雜,而浮點(diǎn)可以用更少的工程資源實(shí)現(xiàn)它們,因?yàn)樗?jiǎn)化了運(yùn)算。使用浮點(diǎn)數(shù)的開(kāi)發(fā)人員無(wú)需擔(dān)心整數(shù)上溢或下溢。
關(guān)于手機(jī),值得記住的是,手機(jī)中通常使用的CPU不僅會(huì)處理浮點(diǎn)運(yùn)算,還會(huì)將其矢量化。因此,如果這是我們的用例,請(qǐng)確保我們?cè)O(shè)計(jì)的代碼能夠進(jìn)行矢量化。
另一個(gè)技巧是在試驗(yàn)系統(tǒng)行為時(shí)將音頻大量寫(xiě)入文件。根據(jù)我們寫(xiě)入的介質(zhì),我們可能需要一個(gè)工作線程,例如一張SD卡。這個(gè)工作線程就像一個(gè)軟件管家,我們可以將音頻數(shù)據(jù)提供給它;它耐心等待,然后將其交給設(shè)備。這意味著我們的核心算法不必等待和阻止運(yùn)行時(shí)的行為。如果要寫(xiě)入多個(gè)文件,請(qǐng)檢查它們是否都從同一位置開(kāi)始。例如,如果我們停止其中一個(gè)文件的開(kāi)頭40ms,我們會(huì)發(fā)現(xiàn)系統(tǒng)中會(huì)出現(xiàn)無(wú)法解釋的40ms延遲。
在音頻信號(hào)處理方面,粗心的人會(huì)遇到很多陷阱。但是,通過(guò)正確的準(zhǔn)備,我們可以通往成功的產(chǎn)品開(kāi)發(fā)。
(原文刊登于EDN姊妹網(wǎng)站Embedded,參考鏈接:Common mistakes in audio signal processing – and how to avoid them,由Ricardo Xie編譯。)
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)聯(lián)系小編進(jìn)行處理。
推薦閱讀:
面向高功率充放電應(yīng)用的先進(jìn)電動(dòng)車(chē)電池?zé)峁芾砑夹g(shù)
如何為汽車(chē)智能配電系統(tǒng)選擇功率開(kāi)關(guān)管
氮化鎵柵極驅(qū)動(dòng)專(zhuān)利:RC負(fù)偏壓關(guān)斷專(zhuān)利技術(shù)之臺(tái)達(dá)電子篇