Linux音頻編程(二)聲卡介紹


一、聲卡

1、聲卡audio interface,它含有hardware buffer,這個hardware buffer是在聲卡里面,不是內存。聲卡的緩存是環狀的,ALSA中是將數據分成連續的片段然后傳到按單元片段傳輸。

2、當我們通過麥克風講話的聲音搜集到聲卡里之后,內存從聲卡設備文件中讀取聲音數據的過程就是錄音過程把內存中的聲音數據寫入到聲卡的設備文件中可以實現音頻文件。

3、我們在/dev/snd/目錄下用ls命令就可以看到相關的聲卡設備。

4、模/數(ADC)轉換器將模擬電壓轉換成離散的樣本值。聲音以固定的時間間隔被采樣,采樣的速率稱為采樣率。把樣本輸出到數/模(DAC)轉換器,比如擴音器,最后轉換成原來的模擬信號。

二、相關設備文件介紹

1、/dev/dsp

用於數字采樣(sampling)和數字錄音(recording)的設備文件,向該設備寫數據時使用聲卡上的D/A轉換器進行放音,而向該設備讀數據時使用聲卡上的A/D轉換器進行錄音。

聲卡使用DSP數字信號處理器來實現模擬信號和數字信號之間的轉換(有D/AA/D轉換。聲卡中的DSP設備在以只讀方式打開/dev/dsp時,使用A/D轉換器變成數字采樣的樣本通過read系統調用從聲卡讀取數據進行聲音的輸入;以只寫方式打開/dev/dsp時,數字信號經過D/A轉換器變成模擬信號通過write進行聲音的輸出。以讀寫的方式打開 /dev/dsp同時進行聲音的輸入和輸出

2、/dev/sequencer合成器

3、/dev/mixer混音器

三、使用

1、在打開聲卡之后可通過ioctl函數來設置聲卡參數,函數如下所示:

int ioctl(int fd, int request, ...);  

//參數fd是打開的文件的描述符,它是在設備打開時獲得的;如果設備比較復雜,那么對它的控制請求相應地也會有很多種。

//參數request是命令,它的目的就是用來區分不同的控制請求;通常說來,在對設備進行控制時還需要有其它參數,這要根據不同的控制請求才能確定,並且可能是與硬件設備直接相關的。

//第三個參數是完成命令的操作需要的參數或返回的結果。它的意義取決於命令參數,可以是單個數,或是指向復雜的數據結構的指針。(由於ioctl函數面向所有設備文件,不同的設備又是千差萬別,所以,第三個參數的意義、函數的返回值、錯誤代碼等等都取決於command。並且,不同的設備,即使是相同的command也有不同的含義,需要的參數和返回值、錯誤代碼等也不同。)

//ioctl函數中相關的命令如下

SOUND_PCM_WRITE_BITS:設置聲卡的量化位數,8或者16,有些聲卡不支持16位;

SOUND_PCM_READ_BITS:獲取當前聲卡的量化位數;

SOUND_PCM_WRITE_CHANNELS:設置聲卡的聲道數目,1或者2,1為單聲道,2為立體聲;

SOUND_PCM_READ_CHANNELS:獲取當前聲卡的聲道數;

SOUND_PCM_WRITE_RATE:設置聲卡的采樣頻率,8K,16K等等;

SOUND_PCM_READ_RATE:獲取聲卡的采樣頻率

1)聲卡讀取數據和向聲卡寫入數據時,具有特定的格式,默認為8位無符號數據、單聲道、8KHz采樣率,可通過ioctl系統調用來改變格式,可調節運行在Linux內核中的聲卡驅動程序中緩沖區的大小,進而達到放音和錄音想要的效果。例如:

//緩沖區大小設置

int setting = 0xnnnnssss;
int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, &setting);

//參數setting實際上由兩部分組成,其低16位標明緩沖區的尺寸,相應的計算公式為buffer_size = 2^ssss

//若參數setting低16位的值為16,那么相應的緩沖區的大小會被設置為65536字節。參數setting的高16位則用來標明分片(fragment)的最大序號,它的取值范圍從2一直到0x7FFF,其中0x7FFF表示沒有任何限制。

//設置聲卡聲道數目

int channels = 0; //0=mono 1=stereo

int result = ioctl(handle, SNDCTL_DSP_STEREO, &channels);

//設置采樣格式

int format = AFMT_U8;

int result = ioctl(handle, SNDCTL_DSP_SETFMT, &format);

//設置采樣頻率

int rate = 22050;
int result = ioctl(handle, SNDCTL_DSP_SPEED, &rate);

//調用ioctl時將第二個參數的值設置為SNDCTL_DSP_SPEED,同時在第三個參數中指定采樣頻率的數值。

//在 Linux下進行音頻編程時最常用到的幾種采樣頻率是11025Hz、16000Hz、22050Hz、32000Hz和44100Hz。

 

2直接使用系統調用控制聲卡的是tinyalsa庫,位於目錄/external/tinyalsa下,編譯生成庫文件libtinyalsa.so(只涉及兩個文件mixer.c,pcm.c),編譯生成工具 tinycaptinymixtinypcminfotinyplay,可用於直接控制音頻通道,進行錄音播音測試。tinyalsa中使用
pcm_open()來打開聲卡
pcm_write()來播放音樂
pcm_read()來錄音

 

3config 的配置很重要,tinyalsa直接從wav文件把channels,rate,等讀出來並配置進聲卡

 //轉換成config

   config.channels = channels;  //聲道數目

    config.rate = rate;  //采樣頻率

    config.period_size = 1024; //周期

    config.period_count = 4;  //count

    if (bits == 32)

        config.format = PCM_FORMAT_S32_LE;  //

    else if (bits == 16)

    config.format = PCM_FORMAT_S16_LE;

    config.start_threshold = 0;

    config.stop_threshold = 0;

    config.silence_threshold = 0;

 

    //

pcm = pcm_open(card, device, PCM_IN, &config);  

 if (!pcm || !pcm_is_ready(pcm)) {   

  printf("Unable to open PCM device (%s)\n",pcm_get_error(pcm));      

  return 0;   

 }

四、

1spdif接口支持rawdatapcmdata模式。

當音頻channel設置成channels=4的時候,spdif會相應設置成rawdata模式。當音頻channel設置成channels=2或者1的時候,spdif會設置成pcmdata模式。spdif是一個獨立的音頻驅動,接口支持alsalib中的標准接口。

2Hdmiaudio支持rawdatapcmdata模式。

當音頻channel設置成channels=4的時候,hdmiaudio會相應設置成rawdata模式。當音頻channel設置成channels=2或者1的時候,hdmiaudio會設置成pcmdata模式。Hdmiaudio是一個獨立的音頻驅動,接口支持alsalib中的標准接口。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM