導航:首頁 > 編程語言 > linux音頻編程

linux音頻編程

發布時間:2022-08-01 17:25:14

linux 編程可以分為幾大類

內核和驅動編程 主要是c
腳本編程 這個多了去了,比如python等等,你可以自己網路一下
簡單的系統調用 主要是c
高級編程 這個高級主要指帶交互畫面、窗口之類 主要是gtk和kde,都是c++語言,後者是以qt為基礎.當然,也有其他優秀的封裝庫
還有系統編程 就是裁剪linux系統
我知道的就這么多
對了,忘了說你提到的網路編程,這是linux的強項
至於圖形編程,任何一個平台都會遇到吧,不知道你這些類是怎麼分出來的

② linux 音頻錄音編程

看看你的fedora是用OSS(Open Sound System,開放聲音系統),還是ALSA(Advanced Linux Sound Architecture),這兩個是不同的。而且你可以隨便自己編一個程序來測試是否打開了音效卡設備。

③ 如何在Linux平台下開發實際的音頻應用程序

一、數字音頻音頻信號是一種連續變化的模擬信號,但計算機只能處理和記錄二進制的數字信號,由自然音源得到的音頻信號必須經過一定的變換,成為數字音頻信號之後,才能送到計算機中作進一步的處理。數字音頻系統通過將聲波的波型轉換成一系列二進制數據,來實現對原始聲音的重現,實現這一步驟的設備常被稱為模/數轉換器(A/D)。A/D轉換器以每秒鍾上萬次的速率對聲波進行采樣,每個采樣點都記錄下了原始模擬聲波在某一時刻的狀態,通常稱之為樣本(sample),而每一秒鍾所采樣的數目則稱為采樣頻率,通過將一串連續的樣本連接起來,就可以在計算機中描述一段聲音了。對於采樣過程中的每一個樣本來說,數字音頻系統會分配一定存儲位來記錄聲波的振幅,一般稱之為采樣分辯率或者采樣精度,采樣精度越高,聲音還原時就會越細膩。數字音頻涉及到的概念非常多,對於在Linux下進行音頻編程的程序員來說,最重要的是理解聲音數字化的兩個關鍵步驟:采樣和量化。采樣就是每隔一定時間就讀一次聲音信號的幅度,而量化則是將采樣得到的聲音信號幅度轉換為數字值,從本質上講,采樣是時間上的數字化,而量化則是幅度上的數字化。下面介紹幾個在進行音頻編程時經常需要用到的技術指標:1. 采樣頻率采樣頻率是指將模擬聲音波形進行數字化時,每秒鍾抽取聲波幅度樣本的次數。采樣頻率的選擇應該遵循奈奎斯特(Harry Nyquist)采樣理論:如果對某一模擬信號進行采樣,則采樣後可還原的最高信號頻率只有采樣頻率的一半,或者說只要采樣頻率高於輸入信號最高頻率的兩倍,就能從采樣信號系列重構原始信號。正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果採用更高的采樣頻率,還可以達到DVD的音質。2. 量化位數量化位數是對模擬音頻信號的幅度進行數字化,它決定了模擬信號數字化以後的動態范圍,常用的有8位、12位和16位。量化位越高,信號的動態范圍越大,數字化後的音頻信號就越可能接近原始信號,但所需要的存貯空間也越大。3. 聲道數聲道數是反映音頻數字化質量的另一個重要因素,它有單聲道和雙聲道之分。雙聲道又稱為立體聲,在硬體中有兩條線路,音質和音色都要優於單聲道,但數字化後占據的存儲空間的大小要比單聲道多一倍二、音效卡驅動出於對安全性方面的考慮,Linux下的應用程序無法直接對音效卡這類硬體設備進行操作,而是必須通過內核提供的驅動程序才能完成。在Linux上進行音頻編程的本質就是要藉助於驅動程序,來完成對音效卡的各種操作。對硬體的控制涉及到寄存器中各個比特位的操作,通常這是與設備直接相關並且對時序的要求非常嚴格,如果這些工作都交由應用程序員來負責,那麼對音效卡的編程將變得異常復雜而困難起來,驅動程序的作用正是要屏蔽硬體的這些底層細節,從而簡化應用程序的編寫。目前Linux下常用的音效卡驅動程序主要有兩種:OSS和ALSA。最早出現在Linux上的音頻編程介面是OSS(Open Sound System),它由一套完整的內核驅動程序模塊組成,可以為絕大多數音效卡提供統一的編程介面。OSS出現的歷史相對較長,這些內核模塊中的一部分(OSS/Free)是與Linux內核源碼共同免費發布的,另外一些則以二進制的形式由4Front Technologies公司提供。由於得到了商業公司的鼎力支持,OSS已經成為在Linux下進行音頻編程的事實標准,支持OSS的應用程序能夠在絕大多數音效卡上工作良好。雖然OSS已經非常成熟,但它畢竟是一個沒有完全開放源代碼的商業產品,ALSA(Advanced Linux Sound Architecture)恰好彌補了這一空白,它是在Linux下進行音頻編程時另一個可供選擇的音效卡驅動程序。ALSA除了像OSS那樣提供了一組內核驅動程序模塊之外,還專門為簡化應用程序的編寫提供了相應的函數庫,與OSS提供的基於ioctl的原始編程介面相比,ALSA函數庫使用起來要更加方便一些。ALSA的主要特點有:支持多種音效卡設備模塊化的內核驅動程序支持SMP和多線程提供應用開發函數庫兼容OSS應用程序ALSA和OSS最大的不同之處在於ALSA是由志願者維護的自由項目,而OSS則是由公司提供的商業產品,因此在對硬體的適應程度上OSS要優於ALSA,它能夠支持的音效卡種類更多。ALSA雖然不及OSS運用得廣泛,但卻具有更加友好的編程介面,並且完全兼容於OSS,對應用程序員來講無疑是一個更佳的選擇。三、編程介面如何對各種音頻設備進行操作是在Linux上進行音頻編程的關鍵,通過內核提供的一組系統調用,應用程序能夠訪問音效卡驅動程序提供的各種音頻設備介面,這是在Linux下進行音頻編程最簡單也是最直接的方法。3.1 訪問音頻設備無論是OSS還是ALSA,都是以內核驅動程序的形式運行在Linux內核空間中的,應用程序要想訪問音效卡這一硬體設備,必須藉助於Linux內核所提供的系統調用(system call)。從程序員的角度來說,對音效卡的操作在很大程度上等同於對磁碟文件的操作:首先使用open系統調用建立起與硬體間的聯系,此時返回的文件描述符將作為隨後操作的標識;接著使用read系統調用從設備接收數據,或者使用write系統調用向設備寫入數據,而其它所有不符合讀/寫這一基本模式的操作都可以由ioctl系統調用來完成;最後,使用close系統調用告訴Linux內核不會再對該設備做進一步的處理。· open系統調用系統調用open可以獲得對音效卡的訪問權,同時還能為隨後的系統調用做好准備,其函數原型如下所示: int open(const char *pathname, int flags, int mode);參數pathname是將要被打開的設備文件的名稱,對於音效卡來講一般是/dev/dsp。參數flags用來指明應該以什麼方式打開設備文件,它可以是O_RDONLY、O_WRONLY或者O_RDWR,分別表示以只讀、只寫或者讀寫的方式打開設備文件;參數mode通常是可選的,它只有在指定的設備文件不存在時才會用到,指明新創建的文件應該具有怎樣的許可權。如果open系統調用能夠成功完成,它將返回一個正整數作為文件標識符,在隨後的系統調用中需要用到該標識符。如果open系統調用失敗,它將返回-1,同時還會設置全局變數errno,指明是什麼原因導致了錯誤的發生。· read系統調用系統調用read用來從音效卡讀取數據,其函數原型如下所示: int read(int fd, char *buf, size_t count);參數fd是設備文件的標識符,它是通過之前的open系統調用獲得的;參數buf是指向緩沖區的字元指針,它用來保存從音效卡獲得的數據;參數count則用來限定從音效卡獲得的最大位元組數。如果read系統調用成功完成,它將返回從音效卡實際讀取的位元組數,通常情況會比count的值要小一些;如果read系統調用失敗,它將返回-1,同時還會設置全局變數errno,來指明是什麼原因導致了錯誤的發生。write系統調用系統調用write用來向音效卡寫入數據,其函數原型如下所示: size_t write(int fd, const char *buf, size_t count);系統調用write和系統調用read在很大程度是類似的,差別只在於write是向音效卡寫入數據,而read則是從音效卡讀入數據。參數fd同樣是設備文件的標識符,它也是通過之前的open系統調用獲得的;參數buf是指向緩沖區的字元指針,它保存著即將向音效卡寫入的數據;參數count則用來限定向音效卡寫入的最大位元組數。如果write系統調用成功完成,它將返迴向音效卡實際寫入的位元組數;如果read系統調用失敗,它將返回-1,同時還會設置全局變數errno,來指明是什麼原因導致了錯誤的發生。無論是read還是write,一旦調用之後Linux內核就會阻塞當前應用程序,直到數據成功地從音效卡讀出或者寫入為止。ioctl系統調用系統調用ioctl可以對音效卡進行控制,凡是對設備文件的操作不符合讀/寫基本模式的,都是通過ioctl來完成的,它可以影響設備的行為,或者返回設備的狀態,其函數原型如下所示: int ioctl(int fd, int request, ...);參數fd是設備文件的標識符,它是在設備打開時獲得的;如果設備比較復雜,那麼對它的控制請求相應地也會有很多種,參數request的目的就是用來區分不同的控制請求;通常說來,在對設備進行控制時還需要有其它參數,這要根據不同的控制請求才能確定,並且可能是與硬體設備直接相關的。close系統調用當應用程序使用完音效卡之後,需要用close系統調用將其關閉,以便及時釋放佔用的硬體資源,其函數原型如下所示: int close(int fd);參數fd是設備文件的標識符,它是在設備打開時獲得的。一旦應用程序調用了close系統調用,Linux內核就會釋放與之相關的各種資源,因此建議在不需要的時候盡量及時關閉已經打開的設備。3.2 音頻設備文件對於Linux應用程序員來講,音頻編程介面實際上就是一組音頻設備文件,通過它們可以從音效卡讀取數據,或者向音效卡寫入數據,並且能夠對音效卡進行控制,設置采樣頻率和聲道數目等等。/dev/sndstat設備文件/dev/sndstat是音效卡驅動程序提供的最簡單的介面,通常它是一個只讀文件,作用也僅僅只限於匯報音效卡的當前狀態。一般說來,/dev/sndstat是提供給最終用戶來檢測音效卡的,不宜用於程序當中,因為所有的信息都可以通過ioctl系統調用來獲得。 Linux提供的cat命令可以很方便地從/dev/sndstat獲得音效卡的當前狀態: [xiaowp@linuxgam sound]$ cat /dev/sndstat /dev/dsp音效卡驅動程序提供的/dev/dsp是用於數字采樣(sampling)和數字錄音(recording)的設備文件,它對於Linux下的音頻編程來講非常重要:向該設備寫數據即意味著激活音效卡上的D/A轉換器進行放音,而向該設備讀數據則意味著激活音效卡上的A/D轉換器進行錄音。目前許多音效卡都提供有多個數字采樣設備,它們在Linux下可以通過/dev/dsp1等設備文件進行訪問。DSP是數字信號處理器(Digital Signal Processor)的簡稱,它是用來進行數字信號處理的特殊晶元,音效卡使用它來實現模擬信號和數字信號的轉換。音效卡中的DSP設備實際上包含兩個組成部分:在以只讀方式打開時,能夠使用A/D轉換器進行聲音的輸入;而在以只寫方式打開時,則能夠使用D/A轉換器進行聲音的輸出。嚴格說來,Linux下的應用程序要麼以只讀方式打開/dev/dsp輸入聲音,要麼以只寫方式打開/dev/dsp輸出聲音,但事實上某些音效卡驅動程序仍允許以讀寫的方式打開/dev/dsp,以便同時進行聲音的輸入和輸出,這對於某些應用場合(如IP電話)來講是非常關鍵的。在從DSP設備讀取數據時,從音效卡輸入的模擬信號經過A/D轉換器變成數字采樣後的樣本(sample),保存在音效卡驅動程序的內核緩沖區中,當應用程序通過read系統調用從音效卡讀取數據時,保存在內核緩沖區中的數字采樣結果將被復制到應用程序所指定的用戶緩沖區中。需要指出的是,音效卡采樣頻率是由內核中的驅動程序所決定的,而不取決於應用程序從音效卡讀取數據的速度。如果應用程序讀取數據的速度過慢,以致低於音效卡的采樣頻率,那麼多餘的數據將會被丟棄;如果讀取數據的速度過快,以致高於音效卡的采樣頻率,那麼音效卡驅動程序將會阻塞那些請求數據的應用程序,直到新的數據到來為止。在向DSP設備寫入數據時,數字信號會經過D/A轉換器變成模擬信號,然後產生出聲音。應用程序寫入數據的速度同樣應該與音效卡的采樣頻率相匹配,否則過慢的話會產生聲音暫停或者停頓的現象,過快的話又會被內核中的音效卡驅動程序阻塞,直到硬體有能力處理新的數據為止。與其它設備有所不同,音效卡通常不會支持非阻塞(non-blocking)的I/O操作。無論是從音效卡讀取數據,或是向音效卡寫入數據,事實上都具有特定的格式(format),默認為8位無符號數據、單聲道、8KHz采樣率,如果默認值無法達到要求,可以通過ioctl系統調用來改變它們。通常說來,在應用程序中打開設備文件/dev/dsp之後,接下去就應該為其設置恰當的格式,然後才能從音效卡讀取或者寫入數據。/dev/audio/dev/audio類似於/dev/dsp,它兼容於Sun工作站上的音頻設備,使用的是mu-law編碼方式。如果音效卡驅動程序提供了對/dev/audio的支持,那麼在Linux上就可以通過cat命令,來播放在Sun工作站上用mu-law進行編碼的音頻文件: [xiaowp@linuxgam sound]$ cat audio.au > /dev/audio由於設備文件/dev/audio主要出於對兼容性的考慮,所以在新開發的應用程序中最好不要嘗試用它,而應該以/dev/dsp進行替代。對於應用程序來說,同一時刻只能使用/dev/audio或者/dev/dsp其中之一,因為它們是相同硬體的不同軟體介面。/dev/mixer在音效卡的硬體電路中,混音器(mixer)是一個很重要的組成部分,它的作用是將多個信號組合或者疊加在一起,對於不同的音效卡來說,其混音器的作用可能各不相同。運行在Linux內核中的音效卡驅動程序一般都會提供/dev/mixer這一設備文件,它是應用程序對混音器進行操作的軟體介面。混音器電路通常由兩個部分組成:輸入混音器(input mixer)和輸出混音器(output mixer)。輸入混音器負責從多個不同的信號源接收模擬信號,這些信號源有時也被稱為混音通道或者混音設備。模擬信號通過增益控制器和由軟體控制的音量調節器後,在不同的混音通道中進行級別(level)調制,然後被送到輸入混音器中進行聲音的合成。混音器上的電子開關可以控制哪些通道中有信號與混音器相連,有些音效卡只允許連接一個混音通道作為錄音的音源,而有些音效卡則允許對混音通道做任意的連接。經過輸入混音器處理後的信號仍然為模擬信號,它們將被送到A/D轉換器進行數字化處理。輸出混音器的工作原理與輸入混音器類似,同樣也有多個信號源與混音器相連,並且事先都經過了增益調節。當輸出混音器對所有的模擬信號進行了混合之後,通常還會有一個總控增益調節器來控制輸出聲音的大小,此外還有一些音調控制器來調節輸出聲音的音調。經過輸出混音器處理後的信號也是模擬信號,它們最終會被送給喇叭或者其它的模擬輸出設備。對混音器的編程包括如何設置增益控制器的級別,以及怎樣在不同的音源間進行切換,這些操作通常來講是不連續的,而且不會像錄音或者放音那樣需要佔用大量的計算機資源。由於混音器的操作不符合典型的讀/寫操作模式,因此除了open和close兩個系統調用之外,大部分的操作都是通過ioctl系統調用來完成的。與/dev/dsp不同,/dev/mixer允許多個應用程序同時訪問,並且混音器的設置值會一直保持到對應的設備文件被關閉為止。為了簡化應用程序的設計,Linux上的音效卡驅動程序大多都支持將混音器的ioctl操作直接應用到聲音設備上,也就是說如果已經打開了/dev/dsp,那麼就不用再打開/dev/mixer來對混音器進行操作,而是可以直接用打開/dev/dsp時得到的文件標識符來設置混音器。/dev/sequencer目前大多數音效卡驅動程序還會提供/dev/sequencer這一設備文件,用來對音效卡內建的波表合成器進行操作,或者對MIDI匯流排上的樂器進行控制,一般只用於計算機音樂軟體中。 四、應用框架在Linux下進行音頻編程時,重點在於如何正確地操作音效卡驅動程序所提供的各種設備文件,由於涉及到的概念和因素比較多,所以遵循一個通用的框架無疑將有助於簡化應用程序的設計。4.1 DSP編程對音效卡進行編程時首先要做的是打開與之對應的硬體設備,這是藉助於open系統調用來完成的,並且一般情況下使用的是/dev/dsp文件。採用何種模式對音效卡進行操作也必須在打開設備時指定,對於不支持全雙工的音效卡來說,應該使用只讀或者只寫的方式打開,只有那些支持全雙工的音效卡,才能以讀寫的方式打開,並且還要依賴於驅動程序的具體實現。Linux允許應用程序多次打開或者關閉與音效卡對應的設備文件,從而能夠很方便地在放音狀態和錄音狀態之間進行切換,建議在進行音頻編程時只要有可能就盡量使用只讀或者只寫的方式打開設備文件,因為這樣不僅能夠充分利用音效卡的硬體資源,而且還有利於驅動程序的優化。下面的代碼示範了如何以只寫方式打開音效卡進行放音(playback)操作: int handle = open("/dev/dsp", O_WRONLY);if (handle == -1) { perror("open /dev/dsp"); return -1;} 運行在Linux內核中的音效卡驅動程序專門維護了一個緩沖區,其大小會影響到放音和錄音時的效果,使用ioctl系統調用可以對它的尺寸進行恰當的設置。調節驅動程序中緩沖區大小的操作不是必須的,如果沒有特殊的要求,一般採用默認的緩沖區大小也就可以了。但需要注意的是,緩沖區大小的設置通常應緊跟在設備文件打開之後,這是因為對音效卡的其它操作有可能會導致驅動程序無法再修改其緩沖區的大小。下面的代碼示範了怎樣設置音效卡驅動程序中的內核緩沖區的大小: int setting = 0xnnnnssss;int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &setting);if (result == -1) { perror("ioctl buffer size"); return -1;}// 檢查設置值的正確性 在設置緩沖區大小時,參數setting實際上由兩部分組成,其低16位標明緩沖區的尺寸,相應的計算公式為buffer_size = 2^ssss,即若參數setting低16位的值為16,那麼相應的緩沖區的大小會被設置為65536位元組。參數setting的高16位則用來標明分片(fragment)的最大序號,它的取值范圍從2一直到0x7FFF,其中0x7FFF表示沒有任何限制。接下來要做的是設置音效卡工作時的聲道(channel)數目,根據硬體設備和驅動程序的具體情況,可以將其設置為0(單聲道,mono)或者1(立體聲,stereo)。下面的代碼示範了應該怎樣設置聲道數目: int channels = 0; // 0=mono 1=stereoint result = ioctl(handle, SNDCTL_DSP_STEREO, &channels);if ( result == -1 ) { perror("ioctl channel number"); return -1;}if (channels != 0) { // 只支持立體聲} 采樣格式和采樣頻率是在進行音頻編程時需要考慮的另一個問題,音效卡支持的所有采樣格式可以在頭文件soundcard.h中找到,而通過ioctl系統調用則可以很方便地更改當前所使用的采樣格式。下面的代碼示範了如何設置音效卡的采樣格式: int format = AFMT_U8;int result = ioctl(handle, SNDCTL_DSP_SETFMT, &format);if ( result == -1 ) { perror("ioctl sample format"); return -1;}// 檢查設置值的正確性 音效卡采樣頻率的設置也非常容易,只需在調用ioctl時將第二個參數的值設置為SNDCTL_DSP_SPEED,同時在第三個參數中指定采樣頻率的數值就行了。對於大多數音效卡來說,其支持的采樣頻率范圍一般為5kHz到44.1kHz或者48kHz,但並不意味著該范圍內的所有頻率都會被硬體支持,在Linux下進行音頻編程時最常用到的幾種采樣頻率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。下面的代碼示範了如何設置音效卡的采樣頻率: int rate = 22050;int result = ioctl(handle, SNDCTL_DSP_SPEED, &rate);if ( result == -1 ) { perror("ioctl sample format"); return -1;}// 檢查設置值的正確性 4.2 Mixer編程音效卡上的混音器由多個混音通道組成,它們可以通過驅動程序提供的設備文件/dev/mixer進行編程。對混音器的操作是通過ioctl系統調用來完成的,並且所有控制命令都由SOUND_MIXER或者MIXER開頭,表1列出了常用的幾個混音器控制命令:名稱作用SOUND_MIXER_VOLUME主音量調節SOUND_MIXER_BASS低音控制SOUND_MIXER_TREBLE高音控制SOUND_MIXER_SYNTHFM合成器SOUND_MIXER_PCM主D/A轉換器SOUND_MIXER_SPEAKERPC喇叭SOUND_MIXER_LINE音頻線輸入SOUND_MIXER_MIC麥克風輸入SOUND_MIXER_CDCD輸入SOUND_MIXER_IMIX回放音量SOUND_MIXER_ALTPCM從D/A 轉換器SOUND_MIXER_RECLEV錄音音量SOUND_MIXER_IGAIN輸入增益SOUND_MIXER_OGAIN輸出增益SOUND_MIXER_LINE1音效卡的第1輸入SOUND_MIXER_LINE2音效卡的第2輸入SOUND_MIXER_LINE3音效卡的第3輸入表1 混音器命令對音效卡的輸入增益和輸出增益進行調節是混音器的一個主要作用,目前大部分音效卡採用的是8位或者16位的增益控制器,但作為程序員來講並不需要關心這些,因為音效卡驅動程序會負責將它們變換成百分比的形式,也就是說無論是輸入增益還是輸出增益,其取值范圍都是從0到100。在進行混音器編程時,可以使用SOUND_MIXER_READ宏來讀取混音通道的增益大小,例如在獲取麥克風的輸入增益時,可以使用如下的代碼: int vol;ioctl(fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &vol);printf("Mic gain is at %d %%\n", vol); 對於只有一個混音通道的單聲道設備來說,返回的增益大小保存在低位位元組中。而對於支持多個混音通道的雙聲道設備來說,返回的增益大小實際上包括兩個部分,分別代表左、右兩個聲道的值,其中低位位元組保存左聲道的音量,而高位位元組則保存右聲道的音量。下面的代碼可以從返回值中依次提取左右聲道的增益大小�4.3 音頻錄放框架下面給出一個利用音效卡上的DSP設備進行聲音錄制和回放的基本框架,它的功能是先錄制幾秒種音頻數據,將其存放在內存緩沖區中,然後再進行回放,其所有的功能都是通過讀寫/dev/dsp設備文件來完成的: /* * sound.c */#include #include #include #include #include #include #include #define LENGTH 3 /* 存儲秒數 */#define RATE 8000 /* 采樣頻率 */#define SIZE 8 /* 量化位數 */#define CHANNELS 1 /* 聲道數目 */ /* 用於保存數字音頻數據的內存緩沖區 */unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/8]; int main(){ int fd; /* 聲音設備的文件描述符 */ int arg; /* 用於ioctl調用的參數 */ int status; /* 系統調用的返回值 */ /* 打開聲音設備 */ fd = open("/dev/dsp", O_RDWR); if (fd < 0) { perror("open of /dev/dsp failed"); exit(1); } /* 設置采樣時的量化位數 */ arg = SIZE; status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_BITS ioctl failed"); if (arg != SIZE) perror("unable to set sample size"); /* 設置采樣時的聲道數目 */ arg = CHANNELS; status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); if (status == -1) perror("SOUND_PCM_WRITE_CHANNELS ioctl failed"); if (arg != CHANNELS) perror("unable to set number of channels"); /* 設置采樣時的采樣頻率 */ arg = RATE; status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); if (status == -1) perror("SOUND_PCM_WRITE_WRITE ioctl failed"); /* 循環,直到按下Control-C */ while (1) { printf("Say something:\n"); status = read(fd, buf, sizeof(buf)); /* 錄音 */ if (status != sizeof(buf)) perror("read wrong number of bytes"); printf("You said:\n"); status = write(fd, buf, sizeof(buf)); /* 回放 */ if (status != sizeof(buf)) perror("wrote wrong number of bytes"); /* 在繼續錄音前等待回放結束 */ status = ioctl(fd, SOUND_PCM_SYNC, 0); if (status == -1) perror("SOUND_PCM_SYNC ioctl failed"); }} 4.4 混音器框架下面再給出一個對混音器進行編程的基本框架,利用它可以對各種混音通道的增益進行調節,其所有的功能都是通過讀寫/dev/mixer設備文件來完成的: /* * mixer.c */#include #include #include #include #include #include /* 用來存儲所有可用混音設備的名稱 */const char *sound_device_names[] = SOUND_DEVICE_NAMES; int fd; /* 混音設備所對應的文件描述符 */int devmask, stereodevs; /* 混音器信息對應的點陣圖掩碼 */char *name; /* 顯示命令的使用方法及所有可用的混音設備 */void usage(){ int i; fprintf(stderr, "usage: %s \n" " %s \n\n" "Where is one of:\n", name, name); for (i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) if ((1

④ 《Linux高級程序設計第三版》pdf下載在線閱讀全文,求百度網盤雲資源

《Linux高級程序設計第三版》網路網盤pdf最新全集下載:
鏈接:https://pan..com/s/1SzK9CKxuU6MKtyiIxWey4w

?pwd=e23v 提取碼:e23v
簡介:《Linux高級程序設計(第3版)》圍繞Linux操作系統「一切都是文件」的特點,講述了Linux操作系統下應用層「一段執行單元(進程)對系統資源(CPU資源、各類文件資源)的管理」。詳細介紹了Linux系統編程環境及編程工具(GCC/Makefile/GDB)、文件管理(文件屬性控制、ANSI以及POSIX標准下文件讀寫操作、終端編程)、進程管理(創建、退出、執行、等待、屬性控制)、進程間通信(管道、消息隊列、共享內存)、進程間同步機制(信號量)、進程間非同步機制(信號)、線程管理(創建、退出、取消等以及屬性控制)、線程間同步(互斥鎖、讀寫鎖、條件變數)、線程與信號以及BSD socket編程中的TCP、UDP、原始套介面、網路伺服器應用開發等內容,並對Linux系統下的音頻應用程序開發做了講解。

《Linux高級程序設計(第3版)》內容豐富、緊扣應用,適合從事Linux下C應用編程的人員閱讀,也適合從事嵌入式Linux開發的人員閱讀。

⑤ 如何安裝linux系統下的ffmpeg

linux下安裝ffmpeg1、下載ffmpeg。2、解壓tar xvfj ffmpeg-0.11.1.tar.bz2得到解壓後的目錄是ffmpeg-0.11.13、配置 ./configure --enable-shared --prefix=/usr/local/ffmpeg其中:--enable-shared 是允許其編譯產生動態庫,在以後的編程中要用到這個幾個動態庫。--prefix設置的安裝目錄。4、編譯並安裝makemake install5、安裝之後在/usr/local/ffmpeg會看到有四個目錄lib 動態鏈接庫位置include 編程要用到頭文件bin 執行文件所在的目錄 share6、為了以後方便編程,我們把lib中的三個鏈接庫libavcodec.so libavformat.so libavutil.so復制到/usr/lib下。把include目錄下的ffmpeg目錄復制到/usr/include下。執行bin目錄下的ffplay,可以去播放音頻或者視頻文件。例如播放1.mp3./ffplay 1.mp3 另外,bin目錄下還有兩個文件:ffmpeg和ffserverffmpeg是一個很好的視頻和音頻的格式轉化工具。網上有很多它的說明文檔。如果不想生成ffserver,只要在./configure的時候加--disable-ffserver即可。7、編程如果寫了一個test.c文件,要包含ffmpeg的頭文件,可以這樣寫:#include 編譯:gcc -o test test.c -lavformat -lavcodec -lavtuil (前提是有第6步的操作)如果沒有第6部的操作,則編譯的時候如下: gcc -o test test.c -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavcodec -lavtuil編譯成功之後,執行的時候還是需要動態庫的支持,還是要把那三個動態庫文件復制到/usr/lib或者/lib中,不然執行的時候會說找不到動態庫鏈接。還有一個方法可以解決這個問題,就是把/usr/local/ffmpeg/lib這個目錄加入到/etc/ld.so.config中,然後執行ldconfig,或者重啟電腦,這樣執行的時候系統就可以從/usr/local/ffmpeg/lib這個目錄下去找這三個動態庫文件了。以上的方式是採用動態庫編譯ffmpeg的,如果在configure的時候不加上--enable-shared的,則採用靜態鏈接的方式,不會生成那三個動態庫。同時生成的ffplay、ffmpeg的執行文件也比較的大,因為他們不需要動態庫的支持,就可以執行。但是不利於再次開發,所以我採用動態鏈接的方式。configure中還有很多的選項,可以通過./configure --help查看,也可以直接查看configure文件。這在配置的時候很重要。

⑥ 怎麼使用libmad

所幸手裡有Altera公司的一個工程,藉助對該工程的分析、minimad.c中少的可憐的注釋和網上搜索的Linux音頻方面的相關知識,反復思考編碼,總算把libmad庫用起來了,現記錄一下其使用方法,在幫助別人的同時也方便自己回頭查詢。在開始之前,最好先把mp3文件格式和Linux音頻編程方面的知識先學習一下,不然後面有的東西可能聽不懂,還有就是一定要熟悉Linux系統,後面的代碼都是在linux系統中用gcc編譯的,在Windows下不能用的。首先看下面幾個問題,這也是我一開始最迷惑的,弄明白這幾個問題了,也就對libmad庫的使用相當熟悉了: minimad.c怎麼編譯?編譯後怎麼運行?運行時的輸入輸出分別是什麼,或者說運行時什麼效果?怎樣播放minimad輸出的數據?或者說怎麼播放解碼後的數據?minimad運行時,mp3數據來源是標准輸入,能不能改為從文件中讀入數據?該怎麼改?minimad運行時首先要將整個mp3文件讀入內存,能不能改成邊解碼邊讀入的形式,比如每次讀入16K,解碼完再讀入16K,而又不影響播放的連貫性,這樣可以節省內存開銷,方便在嵌入式系統中使用;怎樣用libmad做一個簡單的mp3播放器? 一個一個來講吧。 #include #include #include #include #include #include #include #include #include #include "mad.h" #define BUFSIZE 8192 /* * This is a private message structure. A generic pointer to this structure * is passed to each of the callback functions. Put here any data you need * to access from within the callbacks. */ struct buffer { FILE *fp; /*file pointer*/ unsigned int flen; /*file length*/ unsigned int fpos; /*current position*/ unsigned char fbuf[BUFSIZE]; /*buffer*/ unsigned int fbsize; /*indeed size of buffer*/ }; typedef struct buffer mp3_file; int soundfd; /*soundcard file*/ unsigned int prerate = 0; /*the pre simple rate*/ int writedsp(int c) { return write(soundfd, (char *)&c, 1); } void set_dsp() { int format = AFMT_S16_LE; int channels = 2; soundfd = open("/dev/dsp", O_WRONLY); ioctl(soundfd, SNDCTL_DSP_SETFMT, &format); ioctl(soundfd, SNDCTL_DSP_CHANNELS, &channels); } /* * This is perhaps the simplest example use of the MAD high-level API. * Standard input is mapped into memory via mmap(), then the high-level API * is invoked with three callbacks: input, output, and error. The output * callback converts MAD's high-resolution PCM samples to 16 bits, then * writes them to standard output in little-endian, stereo-interleaved * format. */ static int decode(mp3_file *mp3fp); int main(int argc, char *argv[]) { long flen, fsta, fend; int dlen; mp3_file *mp3fp; if (argc != 2) return 1; mp3fp = (mp3_file *)malloc(sizeof(mp3_file)); if((mp3fp->fp = fopen(argv[1], "r")) == NULL) { printf("can't open source file.\n"); return 2; } fsta = ftell(mp3fp->fp); fseek(mp3fp->fp, 0, SEEK_END); fend = ftell(mp3fp->fp); flen = fend - fsta; if(flen fp, 0, SEEK_SET); fread(mp3fp->fbuf, 1, BUFSIZE, mp3fp->fp); mp3fp->fbsize = BUFSIZE; mp3fp->fpos = BUFSIZE; mp3fp->flen = flen; set_dsp(); decode(mp3fp); close(soundfd); fclose(mp3fp->fp); return 0; } /* * This is the input callback. The purpose of this callback is to (re)fill * the stream buffer which is to be decoded. In this example, an entire file * has been mapped into memory, so we just call mad_stream_buffer() with the * address and length of the mapping. When this callback is called a second * time, we are finished decoding. */ static enum mad_flow input(void *data, struct mad_stream *stream) { mp3_file *mp3fp; int ret_code; int unproc_data_size; /*the unprocessed data's size*/ int _size; mp3fp = (mp3_file *)data; if(mp3fp->fpos flen) { unproc_data_size = stream->bufend - stream->next_frame; memcpy(mp3fp->fbuf, mp3fp->fbuf+mp3fp->fbsize-unproc_data_size, unproc_data_size); _size = BUFSIZE - unproc_data_size; if(mp3fp->fpos + _size > mp3fp->flen) { _size = mp3fp->flen - mp3fp->fpos; } fread(mp3fp->fbuf+unproc_data_size, 1, _size, mp3fp->fp); mp3fp->fbsize = unproc_data_size + _size; mp3fp->fpos += _size; /*Hand off the buffer to the mp3 input stream*/ mad_stream_buffer(stream, mp3fp->fbuf, mp3fp->fbsize); ret_code = MAD_FLOW_CONTINUE; } else { ret_code = MAD_FLOW_STOP; } return ret_code; } /* * The following utility routine performs simple rounding, clipping, and * scaling of MAD's high-resolution samples down to 16 bits. It does not * perform any dithering or noise shaping, which would be recommended to * obtain any exceptional audio quality. It is therefore not recommended to * use this routine if high-quality output is desired. */ static inline signed int scale(mad_fixed_t sample) { /* round */ sample += (1L <= MAD_F_ONE) sample = MAD_F_ONE - 1; else if (sample > (MAD_F_FRACBITS + 1 - 16); } /* * This is the output callback function. It is called after each frame of * MPEG audio data has been completely decoded. The purpose of this callback * is to output (or play) the decoded PCM audio. */ static enum mad_flow output(void *data, struct mad_header const *header, struct mad_pcm *pcm) { unsigned int nchannels, nsamples; unsigned int rate; mad_fixed_t const *left_ch, *right_ch; /* pcm->samplerate contains the sampling frequency */ rate= pcm->samplerate; nchannels = pcm->channels; nsamples = pcm->length; left_ch = pcm->samples[0]; right_ch = pcm->samples[1]; /* update the sample rate of dsp*/ if(rate != prerate) { ioctl(soundfd, SNDCTL_DSP_SPEED, &rate); prerate = rate; } while (nsamples--) { signed int sample; /* output sample(s) in 16-bit signed little-endian PCM */ sample = scale(*left_ch++); writedsp((sample >> 0) & 0xff); writedsp((sample >> 8) & 0xff); if (nchannels == 2) { sample = scale(*right_ch++); writedsp((sample >> 0) & 0xff); writedsp((sample >> 8) & 0xff); } } return MAD_FLOW_CONTINUE; } /* * This is the error callback function. It is called whenever a decoding * error occurs. The error is indicated by stream->error; the list of * possible MAD_ERROR_* errors can be found in the mad.h (or stream.h) * header file. */ static enum mad_flow error(void *data, struct mad_stream *stream, struct mad_frame *frame) { mp3_file *mp3fp = data; fprintf(stderr, "decoding error 0x%04x (%s) at byte offset %u\n", stream->error, mad_stream_errorstr(stream), stream->this_frame - mp3fp->fbuf); /* return MAD_FLOW_BREAK here to stop decoding (and propagate an error) */ return MAD_FLOW_CONTINUE; } /* * This is the function called by main() above to perform all the decoding. * It instantiates a decoder object and configures it with the input, * output, and error callback functions above. A single call to * mad_decoder_run() continues until a callback function returns * MAD_FLOW_STOP (to stop decoding) or MAD_FLOW_BREAK (to stop decoding and * signal an error). */ static int decode(mp3_file *mp3fp) { struct mad_decoder decoder; int result; /* configure input, output, and error functions */ mad_decoder_init(&decoder, mp3fp, input, 0 /* header */, 0 /* filter */, output, error, 0 /* message */); /* start decoding */ result = mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); /* release the decoder */ mad_decoder_finish(&decoder); return result; }分享到:

⑦ 海思的音頻 怎麼跟alsa 或者oss 這種音頻編程銜接

在音效卡的驅動中一種是OSS(開放聲音系統),一種是ALSA(先進Linux聲音架構)。OSS是一個商業音效卡驅動程序,需要花錢購買。一般我們現在使用的是ALSA的聲音架構。
Advanced Linux Sound Architecture 的簡稱為 ALSA,譯成中文的意思是 Linux 高級聲音體系,ALSA不僅僅是包括對音效卡的支持和驅動;
它的特徵如下:
1、對所有音頻介面的高效支持,從普通用戶的音效卡到專業級別多路音頻設備;
2、音效卡驅動完全模塊化設計;
3、SMP and thread-safe design.
4、開發庫(alsa-lib) 為程序設計提供了簡單、方便,並且擁有有高級的效果和功能;
5、支持舊版本的OSS API 結口,能為大多數的OSS應用程序提供兼容;OSS是一個商業性的驅動,OSS有一個簡裝本的代碼已經移入內核和ALSA,其中alsa-oss就是;OSS公司據說目前已經並不存在了;我們沒有必要用OSS 公司提供的商業版本;用ALSA和OSS簡裝版足夠;
如何查看硬體晶元;
在Linux操作系統中,所有的硬體都是以晶元組來區分的,品牌並不是最重要的;硬體最重要的標識是晶元組;所以您在討論區求助的時候,只說硬體品牌,而不提供晶元組,大家是幫助不了您的,切記;
我們查看硬體的晶元組是的命令是 lspci -v 或者是dmesg,由於dmesg輸出的信息不太多,不夠直觀;所以經常用的還是lspci -v ;也可以用lshal 獲取;最方便的還是lspci -v;初學者還是用 lspci -v 更好一點;
代碼:
[root@localhost beinan]# lspci -v
我們運行lspci -v 後,如果查看音效卡晶元組,發會現有類似下面的一段;
[root@localhost beinan]# lspci -v
Multimedia audio controller: Intel Corporation 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M)
AC'97 Audio Controller (rev 03)
Subsystem: Hewlett-Packard Company: Unknown device 3080
2.6.11-1.1369_FC4 i686 i686 i386
上面的表示的是系統的內核版本,處理器架構等;lsmod 查看已經載入的內核模塊;
如果一個設備在內核的編譯中是以模塊方式載入的,主要是通過lsmod 來查看;
[root@localhost beinan]# lsmod
可能初學Linux的弟兄會問,內核的mole存放在哪裡,我們能不能自己來手工載入模塊;內核的模塊放在 /lib/moles/內核的版本/kernel/ ,比如在Fedora 4.0 中,我們可以看到如下的:
[root@localhost beinan]# ls /lib/moles/2.6.11-1.1369_FC4/kernel/
arch/crypto/drivers/ fs/lib/ net/ sound/其中,sound 就是音效卡模塊存放目錄,大多數的硬體驅動放在 drivers目錄,fs 是文件系統模塊的目錄;net是與網路有關的存放目錄,比如一些網路協議支持的模塊、防火牆支持的模塊等;arch 是cpu方面 ... ...
如果我們想自己載入模塊,就到這些目錄中查看相應模塊的信息,然後用 modprobe 來載入;
[root@localhost beinan]# modinfo snd-intel8x0
查看一個模塊的信息,我們用 modinfo 來查看,所要查看的模塊不要帶 .ko 或者.o 之類的;比如查看到類似下面的信息;
description: Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7012; Ali 5455
通過這個我們足可以知道這是Intel 集成音效卡,通過lspci -v 得到的音效卡信息,感覺他們很相近;所以就能嘗試用這個模塊來驅動;
[root@localhost beinan]# modprobe snd-intel8x0
用 modprobe 載入了模塊,然後我們通過 lsmod 就能看到了;對於音效卡模塊是這么載入的,其它設備的驅動模塊也是如此。

⑧ linux ( fedora 12 ) 音頻編程 找不到音效卡文件

看看你的fedora是用OSS(Open Sound System,開放聲音系統),還是ALSA(Advanced Linux Sound Architecture),這兩個是不同的。而且你可以隨便自己編一個程序來測試是否打開了音效卡設備。

⑨ 跪求linux大神,小弟正在研究linux音效卡方面的編程,想知道如何對/dev/mixer的操作可以實現聲音的合成,就

alsa 支持軟合成。詳細請看他的相關文檔
另外還有一些合成服務程序。比如 arts 、esound 。詳細請看他的相關文檔。這個其實是你把聲音數據發給這種聲音伺服器程序,他們合成後轉發給音效卡。這會有輕微的延遲(現在來說硬體性能足夠保證感覺到是「實時」而不是延遲)。

互不幹涉是硬體的功能,有些硬體不支持(其實只有高端支持),這要看驅動。
Windows 用的其實是軟體的合成。類似 arts 、esound 。 Windows 曾經也支持獨占音效卡的那種方式,那樣可以保證音頻輸出的質量和實時性。
你想參考,去看這種音頻合成服務的源代碼就行了。

混音的演算法我就不知道什麼地方找了,不過很多音頻編輯程序應該都有相關的演算法吧?Linux 下面有一些音頻編輯軟體的。
另外有些播放器支持 crossfade ,這也是混合兩個歌曲的演算法,源代碼應該可以參考。

閱讀全文

與linux音頻編程相關的資料

熱點內容
如何做淘寶代理伺服器 瀏覽:658
gz壓縮文件夾 瀏覽:177
字母h從右往左跑的c語言編程 瀏覽:127
安卓手機如何擁有蘋果手機橫條 瀏覽:765
業余編程語言哪個好學 瀏覽:137
按照文件夾分個壓縮 瀏覽:104
航空工業出版社單片機原理及應用 瀏覽:758
如何在電信app上綁定親情號 瀏覽:376
安卓的怎麼用原相機拍月亮 瀏覽:805
配音秀為什麼顯示伺服器去配音了 瀏覽:755
c盤清理壓縮舊文件 瀏覽:325
app怎麼交付 瀏覽:343
圖蟲app怎麼才能轉到金幣 瀏覽:175
如何做徵文app 瀏覽:446
用什麼app管理斐訊 瀏覽:169
安卓如何下載寶可夢劍盾 瀏覽:166
編譯器開發屬於哪個方向 瀏覽:940
megawin單片機 瀏覽:687
以色列加密貨幣監督 瀏覽:909
程序員前端現在怎麼樣 瀏覽:499