0 引 言
LabVIEW 是美國NI公司1986年推出的一種圖形化的編程語言和開發(fā)環(huán)境。作為虛擬儀器開發(fā)平臺,,由于其圖形化的編程方式具有簡單易學(xué),、直觀方便、功能強(qiáng)大等特點,,是很多工程設(shè)計人員進(jìn)行虛擬儀器開發(fā)的首選,。生產(chǎn)者/消費者設(shè)計模式是NI公司最新推出的程序設(shè)計概念,它從主/從設(shè)計模式發(fā)展而來,,生產(chǎn)者/消費者設(shè)計模式將生產(chǎn)和消費數(shù)據(jù)速度不同的任務(wù)分開處理,,大大提高了不同速率的多個循環(huán)之間數(shù)據(jù)共享的能力,對于多任務(wù)處理和實時性,、連續(xù)性要求嚴(yán)格的程序設(shè)計,,生產(chǎn)者/消費者設(shè)計模式是較好的選擇。在虛擬儀器系統(tǒng)中,,硬件解決信號的輸入和輸出,,軟件可以方便地更新儀器系統(tǒng)的功能,以適應(yīng)不同使用者的需要,。其中信號的輸入部分一般使用數(shù)據(jù)采集卡實現(xiàn),,商用的數(shù)據(jù)采集卡具有較大的逋用性。普通聲卡具有16位的量化精度,、數(shù)據(jù)采集頻率是44 kHz,,完全可以滿足特定音頻信號范圍內(nèi)數(shù)據(jù)采集的需要,,個別性能指標(biāo)還優(yōu)于商用數(shù)據(jù)采集卡,而價格卻為商用數(shù)據(jù)采集卡的十幾分之一甚至幾十分之一,。若保證信號采集的逼真性,,在采集過程中的連續(xù)性和實時控制顯得尤為重要。
本文以LabVIEW為平臺,,著重介紹了生產(chǎn)者/消費者模式的實現(xiàn),,以及在實時控制的連續(xù)音頻采集系統(tǒng)中的應(yīng)用。
1 生產(chǎn)者/消費者設(shè)計模式概念及其實現(xiàn)
1.1 生產(chǎn)者/消費者設(shè)計模式概念
生產(chǎn)者/消費者設(shè)計模式包括多個并行循環(huán),,每個循環(huán)以不同的速率執(zhí)行任務(wù),。一個循環(huán)作為生產(chǎn)數(shù)據(jù)的循環(huán),,其他循環(huán)作為消費數(shù)據(jù)的循環(huán),。生產(chǎn)數(shù)據(jù)的循環(huán)控制所有消費數(shù)據(jù)的循環(huán),并且使用通信技術(shù)與它們進(jìn)行通信,。
1.2 生產(chǎn)者循環(huán)與消費者循環(huán)之間的通信
在LabVIEW程序設(shè)計過程中,,變量(局部變量和全局變量)、通知器,、隊列常用于多個循環(huán)之間傳遞數(shù)據(jù),。
LabVIEW中的變量是程序框圖中的元素,通過它可以在另一位置訪問或存儲數(shù)據(jù),。根據(jù)不同的變量類型,,數(shù)據(jù)的實際位置也不一樣。局部變量將數(shù)據(jù)存儲在前面板的輸入控件和顯示控件中,,全局變量和單進(jìn)程共享變量將數(shù)據(jù)存儲在特殊的通過多個VI可以訪問的倉庫中,。不管變量將數(shù)據(jù)存儲在何處,所有的變量都可以在不使用連線連接兩個地方的條件下把數(shù)據(jù)從一個地方傳遞到另一個地方,,而不必使用正常的數(shù)據(jù)流,。但是變量的使用有著其自身的缺點,變量不僅不能保證各個循環(huán)之間的同步,,而且使用變量會破壞LabVIEW的數(shù)據(jù)流模式,,在對變量進(jìn)行讀寫操作時容易產(chǎn)生內(nèi)存拷貝,浪費內(nèi)存資源,,影響系統(tǒng)運(yùn)行效率,。
變量還允許競爭狀態(tài)的出現(xiàn),競爭狀態(tài)不容易識別和調(diào)試,,因為輸出取決于操作系統(tǒng)執(zhí)行排定的任務(wù)和外部時間定時的順序,。任務(wù)之間和任務(wù)同計算機(jī)之間的交互方式,以及外部時間的任意定時都使這種順序變得隨機(jī),。很多情況下,,帶有競爭狀態(tài)的代碼會在數(shù)千次測試中返回相同的結(jié)果,,但仍然可能會在運(yùn)行時返回一個不同的結(jié)果。
對生產(chǎn)者/消費者設(shè)計模式的一個更有效的實現(xiàn)是使用通知器和隊列使數(shù)據(jù)傳輸保持同步,。通知器在發(fā)出數(shù)據(jù)可用的通知時,,將同時發(fā)送數(shù)據(jù)。使用通知器將數(shù)據(jù)從主循環(huán)傳送到從循環(huán)消除了和競爭狀態(tài)相關(guān)的問題,。使用通知器還有同步的好處,,因為數(shù)據(jù)可用時,主從循環(huán)都已完成定時,,并準(zhǔn)備實現(xiàn)一個良好的生產(chǎn)者/消費者設(shè)計模式,。但是通知器不會緩沖數(shù)據(jù),如果主循環(huán)在從循環(huán)讀取第一份數(shù)據(jù)之前發(fā)送另一份數(shù)據(jù),,那么原來那份數(shù)據(jù)就會被覆蓋并丟失,。隊列類似于通知器。但它可以存儲多份數(shù)據(jù),,默認(rèn)情況下,,隊列按照FIFO(先進(jìn)先出)的方式執(zhí)行。因此,,第一份插入隊列的數(shù)據(jù),,也是第一份從隊列中刪除的數(shù)據(jù)。在實時控制的連續(xù)音頻信號采集過程中,,由于需要處理許多用戶界面的事件,,為了不造成數(shù)據(jù)丟失,選擇隊列在各個循環(huán)之間傳遞數(shù)據(jù),,實現(xiàn)過程如圖1所示,。
如圖1所示,在循環(huán)開始使用“獲取隊列引用”函數(shù)之前,,隊列就已經(jīng)創(chuàng)建完畢,。生產(chǎn)者循環(huán)使用“元素入隊列”函數(shù)向隊列中添加數(shù)據(jù)。消費者循環(huán)使用“元素出隊列”函數(shù)從隊列中移除數(shù)據(jù),。消費者循環(huán)一直到隊列中的數(shù)據(jù)可用時才執(zhí)行,。
可見,在此生產(chǎn)者/消費者設(shè)計模式中,,兩個循環(huán)均被同步為與生產(chǎn)者循環(huán)一致,。消費者循環(huán)只在隊列中的數(shù)據(jù)可用時才執(zhí)行。這樣就保證了消費者循環(huán)執(zhí)行任務(wù)的連續(xù)性和高效性,。并且,,隊列用于循環(huán)之間的數(shù)據(jù)傳遞,創(chuàng)建全局可用的位于隊列中的數(shù)據(jù),而且在添加新的數(shù)據(jù)到隊列時,,避免了丟失數(shù)據(jù)的可能性,。
2 實時控制的連續(xù)音頻信號采集系統(tǒng)
2.1 聲卡簡介
從數(shù)據(jù)采集的角度看,聲卡是一種音頻范圍內(nèi)的數(shù)據(jù)采集卡,,是計算機(jī)與外部模擬量環(huán)境聯(lián)系的重要途徑,。一般聲卡都是由以下幾部分組成:聲音控制/處理芯片,功放芯片,,聲音輸入/輸出端口等,。
聲音控制/處理芯片是聲卡的核心,集成了采樣保持,、A/D轉(zhuǎn)換,、D/A轉(zhuǎn)換、音效處理等電路,,它決定了聲卡的性能和檔次,,基本功能包括對聲波采樣和回放控制、處理MIDI指令等,,有的廠家還加進(jìn)了混響,、合聲、音場調(diào)整等功能,。
功放芯片完成信號的功率放大以推動喇叭發(fā)聲工作。聲音輸入/輸出端口是音頻信號的輸入和輸出,,它主要有外接端口和內(nèi)接端口,。外接端口有“SPK Out”喇叭輸出端口,“Wave Out(或Line Out)”線性輸出端口,,“Line In"線性輸入端口,,“MIC”麥克風(fēng)輸入端口,還有MIDI端口,,連接電子樂器以及連接游戲控制器,。內(nèi)接端口是內(nèi)置的輸入/輸出端口,是CD音頻接口,,通過3~4針的音頻線直接連接,。Line In接口和MIC都可以用于外部音頻信號的輸入,只不過后者可接入較弱的信號,,幅值大約為0.02~O.2 V,,顯然這個信號較易受到干擾,因而常使用Line In,,它可接入幅值約不超過1 V的信號,。
市面上的聲卡主流都是16位的,聲卡的最高采樣頻率是44.1 kHz,民用的聲卡一般將采樣頻率設(shè)為4檔,,分別為44.1 kHz,,22.05 kHz,11.025 kHz和8 kH,。與一般的數(shù)據(jù)采集卡不同,,聲卡的D/A和A/D功能都是連續(xù)狀態(tài)的。
2.2 具體設(shè)計
根據(jù)聲卡的性能指標(biāo),,將聲卡初始設(shè)置為雙聲遣,、44 100 Hz采樣頻率、16位采樣精度,。要使采集到的音頻信號達(dá)到逼真的效果,,要求信號的采集過程保持連續(xù),但實時控制要求程序?qū)τ脩艚缑娴目丶龀鲰懥?,這就在采集的連續(xù)性和對用戶的響應(yīng)方面產(chǎn)生了矛盾,。本音頻信號采集系統(tǒng),運(yùn)用生產(chǎn)者/消費者程序設(shè)計模式,,很好地解決了這一矛盾,,使生產(chǎn)者循環(huán)完成對用戶界面的響應(yīng),消費者循環(huán)完成音頻信號的采集任務(wù),,從而不僅提高了整個信號采集過程的效率,,而且使采集的語音信號效果逼真。圖2是實際音頻信號采集系統(tǒng)前面板,。
主要程序框圖如圖3所示,,在循環(huán)開始前,使用“獲取隊列引用”函數(shù)創(chuàng)建消息隊列,。生產(chǎn)者循環(huán)使用“元素入隊列”函數(shù)向隊列中添加數(shù)據(jù),。消費者循環(huán)使用“元素出隊列”函數(shù)從隊列中獲取消息并移除數(shù)據(jù)。
該設(shè)計模式允許消費者循環(huán)以固有速度采集信號的同時,,生產(chǎn)者循環(huán)完成對用戶界面的響應(yīng),,生產(chǎn)者循環(huán)中采用事件結(jié)構(gòu),事件結(jié)構(gòu)的延時時間為100 ms,,采用輪詢操作,,處理用戶界面各個控件的響應(yīng),對信號采集進(jìn)行實時控制,,同時為了不影響消費者循環(huán)中信號采集的連續(xù)性,,并不是每一個用戶事件都通過隊列產(chǎn)生消息,通知消費者循環(huán)重新配置信號采集,,只有在聲卡配置參數(shù)(采樣點數(shù),、采樣率)發(fā)生改變時,,生產(chǎn)者循環(huán)使用“發(fā)送通知”函數(shù)產(chǎn)生消息,以便通過“ 等待通知”函數(shù)通知消費者循環(huán),。
消費者循環(huán)內(nèi)部是狀態(tài)機(jī)結(jié)構(gòu),,在第一次循環(huán)時進(jìn)入“SetUp”分支,進(jìn)行聲卡的初始化配置,,從下次循環(huán)開始,,在其他控件發(fā)生改變而有關(guān)聲卡配置的參數(shù)不發(fā)生變化時,生產(chǎn)者循環(huán)不會產(chǎn)生消息隊列,,消費者循環(huán)中在“daq”分支和“Wait”分支間進(jìn)行,,“Wait”分支僅檢查消息隊列中是否有消息,如果沒有轉(zhuǎn)“daq”分支進(jìn)行數(shù)據(jù)采集,,而不會進(jìn)入聲卡配置的“SetUp”分支,,這樣不僅保證了獨立的采集過程不受影響,而且由用戶界面引起的任何延時(如顯示對話框)都不會導(dǎo)致采集過程的循環(huán)操作產(chǎn)生延時,,從而保證采集音頻信號的連續(xù)性,。
在用戶改變聲卡配置參數(shù)發(fā)生時,生產(chǎn)者循環(huán)響應(yīng)該事件,,“元素入隊列”函數(shù)向隊列中添加消息,,消費者循環(huán)“Wait”分支中的“元素出隊列”函數(shù)從隊列中移出消息,在下次循環(huán)時進(jìn)入“Setup”分支進(jìn)行聲卡參數(shù)配置,,然后轉(zhuǎn)入“daq”分支繼續(xù)進(jìn)行信號采集,。在“daq”分支中除進(jìn)行數(shù)據(jù)采集外,還對信號進(jìn)行功率譜分析,,并將信號保存在一個硬盤文件中,。
通過大量實驗發(fā)現(xiàn)采用生產(chǎn)者/消費者設(shè)計模式設(shè)計的音頻信號采集系統(tǒng)能夠有效避免在采集過程中出現(xiàn)的聲音中斷和失真現(xiàn)象,較之以前基于其他模式的設(shè)計有一定的優(yōu)勢,。
3 結(jié) 語
在LabVIEW程序設(shè)計過程中,并行循環(huán)之問的數(shù)據(jù)傳遞必須進(jìn)行妥善處理,,否則就會出現(xiàn)死循環(huán)等預(yù)想不到的錯誤,。該文介紹的生產(chǎn)者/消費者設(shè)計模式不僅使并行循環(huán)間傳遞數(shù)據(jù)的邏輯關(guān)系更加簡潔明了,使得程序的修改維護(hù)更加方便,,而且大大提高了程序運(yùn)行的效率,。本文只是利用一個簡單的實時控制的連續(xù)音頻信號采集系統(tǒng)介紹了此模式的應(yīng)用,闡明了這種設(shè)計模式的思想,,在用LabVIEW設(shè)計如網(wǎng)絡(luò)通信程序等要求準(zhǔn)確且響應(yīng)速度快的實時控制程序時,,生產(chǎn)者/消費者模式有很好的借鑒意義。