⑴ ubuntu alsa聲音獨占問題怎麼解決
Ubuntu下應用程序獨占音頻聲道的問題解決【方法一】(針對無聲或音頻獨占)幹掉Pulseaudio,只使用Alsa執行以下命令:sudo apt-get install alsa-oss libasound2 libasound2-pluginssudo mv /etc/X11/Xsession.d/70pulseaudio ~/gconftool-2 -s -t bool /apps/gnome_settings_daemon/plugins/sound/active false#注意:gconftool-2 false 整個是一條命令,請輸入在同一行。asoundconf unset-pulseaudiosudo update-rc.d -f pulseaudio remove然後執行asoundconf list輸出應該是類似這樣的情形:Names of available sound cards:Intel(記下你的音效卡名,比如這里的Intel)然後執行:asoundconf set-default-card Intel(Intel請替換為你的音效卡名)(補充:個別用戶會出現真正的音效卡名和HDMI兩個選項,請注意不要選HDMI(除非你輸出到液晶電視))如果想保留登入時的系統提示音,請編輯~/.bashrc文件:gedit ~/.bashrc在文件末尾加上:export SDL_audiodriver=alsa最後,打開系統->首選項->音效,將從上往下數前四個選項都選成 ALSA - Advanced Felix註:經測試,不這么做好像也沒問題。至此,屏蔽pulseaudio並設置alsa已經完全解決。【方法二】(針對音頻獨占)我們讓已經在成功運行於PulseAudio的繼續使用PulseAudio。只支持ALSA的軟體,繼續使用ALSA。解決方法:gksu gedit /etc/pulse/default.pa找到:#load-mole mole-alsa-sink 改為load-mole mole-alsa-sink device=dmix找到:load-mole mole-suspend-on-idle改為#load-mole mole-suspend-on-idle(重新logout再login)另外:找到: (解決錄音問題,如skype和audacity)load-mole mole-hal-detect改為:#load-mole mole-hal-detect這樣,通過使用dmix,PulseAudio就不會霸佔整個audio系統。PulseAudio將成為alsa的其中一個Mix Channel。然後,ALSA和PulseAudio便能很好地共存。以後都不再需要什麼libflashsupport for pulseaudio了。還有,安裝PulseAudio的控制器,好好享受PulseAudio的優勢吧。sudo apt-get install padevchooser【方法三】(針對無聲)(註:如果點擊屏幕右上的小喇叭圖標,出現一個錯誤提示,則可以直接採用此方法)如果以上設置仍然無效,可以嘗試下載編譯安裝新版的alsa(註:安裝之前,請確認自己的內核為源里的最新版)首先到/下載最新的alsa-driver,alsa-lib和alsa-utils。假設下載的文件放在~/alsa (/home/用戶名/alsa)。首先進行解壓:tar jxvf alsa-driver-xxx.tar.bz2tar jxvf alsa-lib-xxx.tar.bz2tar jxvf alsa-utils-xxx.tar.bz2然後分別編譯安裝cd ./alsa-driver-xxx./configure && makesudo make installcd ../alsa-lib-xxx./configure && makesudo make installcd ../alsa-utils-xxx./configure && makesudo make install重啟計算機(注意不是重啟X)
⑵ 請教Linux下ALSA聲道切換
解各參數含義及些基本概念
本度(sample):本記錄音頻數據基本單位見8位16位
通道數(channel):該參數1表示單聲道2則立體聲
楨(frame):楨記錄聲音單元其度本度與通道數乘積
采率(rate):每秒鍾采數該數針楨言
周期(period):音頻設備處理所需要楨數於音頻設備數據訪問及音頻數據存儲都單位
交錯模式(interleaved):種音頻數據記錄式交錯模式數據連續楨形式存放即首先記錄完楨1左聲道本右聲道本(假設立體聲格式)再始楨2記錄非交錯模式首先記錄周期內所楨左聲道本再記錄右聲道本數據連續通道式存儲數情況我需要使用交錯模式
period(周期):硬體斷間間隔間表示輸入延
音效卡介面指針指示音效卡硬體緩存區前讀寫位置要介面運行指針循環指向緩存區某位置
frame size = sizeof(one sample) * nChannels
alsa配置緩存(buffer)周期(size)runtime幀(frames)形式存儲
period_bytes = frames_to_bytes(runtime, runtime->period_size);
bytes_to_frames()
The period and buffer sizes are not dependent on the sample format because they are measured in frames; you do not need to change them.
ALSA聲音編程介紹
ALSA表示高級Linux聲音體系結構(Advanced Linux Sound Architecture)由系列內核驅應用程序編譯介面(API)及支持Linux聲音實用程序組篇文章我簡單介紹ALSA項目基本框架及軟體組主要集介紹PCM介面編程包括您自實踐程序示例
您使用ALSA原能新並唯用聲音API您想完低級聲音操作便能夠化控制聲音並化提高性能或者您使用其聲音API沒特性ALSA選擇您已經寫音頻程序能想要ALSA音效卡驅添加本支持您音頻興趣想播放音頻文件高級API更選擇比SDL,OpenAL及些桌面環境提供工具集另外您能ALSA支持Linux環境使用ALSA
ALSA歷史
ALSA項目發起起Linux音效卡驅(OSS/Free drivers)沒積極維護並且落於新音效卡技術Jaroslav Kysela早先寫音效卡驅並由始ALSA項目隨便更發者加入發隊伍更音效卡支持API結構重組
Linux內核2.5發程ALSA合並官源碼樹發布內核2.6ALSA已經內建穩定內核版本並廣泛使用
數字音頻基礎
聲音由變化氣壓組麥克風轉換器轉換電形式模/數(ADC)轉換器模擬電壓轉換離散本值聲音固定間間隔采采速率稱采率本輸數/模(DAC)轉換器比擴音器轉換原模擬信號
本位表示本影響聲音轉換數字信號精確程度素另主要素采率奈奎斯特(Nyquist)理論要離散系統奈奎斯特頻率高於採信號高頻率或帶寬避免混疊現象
ALSA基礎
ALSA由許音效卡音效卡驅程序組同提供稱libasoundAPI庫應用程序發者應該使用libasound內核ALSA介面libasound提供高級並且編程便編程介面並且提供設備邏輯命名功能發者甚至需要知道類似設備文件低層介面相反OSS/Free驅內核系統調用級編程要求發者提供設備文件名並且利用ioctrl實現相應功能向兼容ALSA提供內核模塊模擬OSS前許OSS基礎發應用程序需要任何改ALSA運行另外libaoss庫模擬OSS需要內核模塊
ALSA包含插件功能使用插件擴展新音效卡驅包括完全用軟體實現虛擬音效卡ALSA提供系列基於命令行工具集比混音器(mixer)音頻文件播放器(aplay)及控制特定音效卡特定屬性工具
ALSA體系結構
ALSA API解幾主要介面:
1 控制介面:提供管理音效卡注冊請求用設備通用功能
2 PCM介面:管理數字音頻放(playback)錄音(capture)介面本文續總結重點放介面發數字音頻程序用介面
3 Raw MIDI介面:支持MIDI(Musical Instrument Digital Interface),標准電樂器些API提供音效卡MIDI匯流排訪問原始介面基於MIDI事件工作由程序員負責管理協議及間處理
4 定器(Timer)介面:同步音頻事件提供音效卡間處理硬體訪問
5 序器(Sequencer)介面
6 混音器(Mixer)介面
設備命名
API庫使用邏輯設備名設備文件設備名字真實硬體名字插件名字硬體名字使用hw:i,j格式其i卡號j塊音效卡設備號第聲音設備hw:0,0.別名默認引用第塊聲音設備並且本文示例真用插件使用另外唯名字比plughw:,表示插件插件提供硬體設備訪問提供像采率轉換軟體特性硬體本身並支持特性
聲音緩存數據傳輸
每音效卡都硬體緩存區保存記錄本緩存區足夠滿音效卡產斷內核音效卡驅使用直接內存(DMA)訪問通道本傳送內存應用程序緩存區類似於放任何應用程序使用DMA自緩存區數據傳送音效卡硬體緩存區
硬體緩存區環緩存說數據達緩存區末尾重新緩存區起始位置ALSA維護指針指向硬體緩存及應用程序緩存區數據操作前位置內核外部看我應用程序緩存區興趣所本文討論應用程序緩存區
應用程序緩存區通ALSA庫函數調用控制緩存區傳輸操作能導致接受延遲我稱延(latency)解決問題ALSA緩存區拆系列周期(period)(OSS/Free叫片斷fragments).ALSAperiod單元傳送數據
周期(period)存儲些幀(frames)每幀包含間點所抓取本於立體聲設備幀包含兩信道本圖1展示解程:緩存區解周期幀本圖包含些假定數值圖左右信道信息交替存儲幀內稱交錯(interleaved)模式非交錯模式信道所本數據存儲另外信道數據
Over and Under Run
音效卡數據總連續硬體緩存區應用程序緩存區間傳輸例外錄音例應用程序讀取數據夠快循環緩存區新數據覆蓋種數據丟失稱overrun.放例應用程序寫入數據緩存區速度夠快緩存區"餓死"錯誤稱"underrun"ALSA文檔兩種情形統稱"XRUN"適設計應用程序化XRUN並且恢復
典型聲音程序
使用PCM程序通類似面偽代碼:
打放或錄音介面
設置硬體參數(訪問模式數據格式信道數采率等等)
while 數據要處理:
讀PCM數據(錄音)
或 寫PCM數據(放)
關閉介面
我文看些工作代碼我建議您Linux系統測試運行些代碼查看輸並嘗試修改推薦代碼本文相關所實例清單FTP獲取:ftp.ssc.com/pub/lj/listings/issue126/6735.tgz
Listing 1. Display Some PCM Types and Formats
#include asoundlib.h>
int main() {
int val;
printf("ALSA library version: %s/n",
SND_LIB_VERSION_STR);
printf("/nPCM stream types:/n");
for (val = 0; val <= SND_PCM_STREAM_LAST; val++)
printf(" %s/n",
snd_pcm_stream_name((snd_pcm_stream_t)val));
printf("/nPCM access types:/n");
for (val = 0; val <= SND_PCM_ACCESS_LAST; val++)
printf(" %s/n",
snd_pcm_access_name((snd_pcm_access_t)val));
printf("/nPCM formats:/n");
for (val = 0; val <= SND_PCM_FORMAT_LAST; val++)
if (snd_pcm_format_name((snd_pcm_format_t)val)
!= NULL)
printf(" %s (%s)/n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
printf("/nPCM subformats:/n");
for (val = 0; val <= SND_PCM_SUBFORMAT_LAST;
val++)
printf(" %s (%s)/n",
snd_pcm_subformat_name((
snd_pcm_subformat_t)val),
snd_pcm_subformat_description((
snd_pcm_subformat_t)val));
printf("/nPCM states:/n");
for (val = 0; val <= SND_PCM_STATE_LAST; val++)
printf(" %s/n",
snd_pcm_state_name((snd_pcm_state_t)val));
return 0;
}
清單顯示些ALSA使用PCM數據類型參數首先需要做包括文件些文件包含所庫函數聲明其顯示ALSA庫版本
程序剩部迭代些PCM數據類型流類型始ALSA每迭代值提供符號量名並且提供功能函數顯示某特定值描述字元串看ALSA支持許格式我1.0.15版本支持達36種格式
程序必須鏈接alsalib庫通編譯需要加-lasound選項些alsa庫函數使用dlopen函數及浮點操作所您能需要加-ldl,-lm選項
面該程序Makefile:
CC=gcc
TARGET=test
SRC=$(wildcard *.c)
OBJECT= ${SRC:.c=.o}
INCLUDES=-I/usr/include/alsa
LDFLAGS=-lasound
all:$(TARGET)
$(OBJECT):$(SRC)
$(CC) -c $(INCLUDES) $<
$(TARGET):$(OBJECT)
$(CC) -o $@ $< $(LDFLAGS)
.PHONY:clean
clean:
@rm -rf $(OBJECT) $(TARGET) *~
Listing 2. Opening PCM Device and Setting Parameters
/*
This example opens the default PCM device, sets
some parameters, and then displays the value
of most of the hardware parameters. It does not
perform any sound playback or recording.
*/
/* Use the newer ALSA API */
#define ALSA_PCM_NEW_HW_PARAMS_API
/* All of the ALSA library API is defined
* in this header */
#include asoundlib.h>
int main() {
int rc;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val, val2;
int dir;
snd_pcm_uframes_t frames;
/* Open PCM device for playback. */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s/n",
snd_strerror(rc));
exit(1);
}
/* Allocate a hardware parameters object. */
snd_pcm_hw_params_alloca(?ms);
/* Fill it in with default values. */
snd_pcm_hw_params_any(handle, params);
/* Set the desired hardware parameters. */
/* Interleaved mode */
snd_pcm_hw_params_set_access(handle, params,
SND_PCM_ACCESS_RW_INTERLEAVED);
/* Signed 16-bit little-endian format */
snd_pcm_hw_params_set_format(handle, params,
SND_PCM_FORMAT_S16_LE);
/* Two channels (stereo) */
snd_pcm_hw_params_set_channels(handle, params, 2);
/* 44100 bits/second sampling rate (CD quality) */
val = 44100;
snd_pcm_hw_params_set_rate_near(handle,
params, &val, &dir);
/* Write the parameters to the driver */
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s/n",
snd_strerror(rc));
exit(1);
}
/* Display information about the PCM interface */
printf("PCM handle name = '%s'/n",
snd_pcm_name(handle));
printf("PCM state = %s/n",
snd_pcm_state_name(snd_pcm_state(handle)));
snd_pcm_hw_params_get_access(params,
(snd_pcm_access_t *) &val);
printf("access type = %s/n",
snd_pcm_access_name((snd_pcm_access_t)val));
snd_pcm_hw_params_get_format(params, &val);
printf("format = '%s' (%s)/n",
snd_pcm_format_name((snd_pcm_format_t)val),
snd_pcm_format_description(
(snd_pcm_format_t)val));
snd_pcm_hw_params_get_subformat(params,
(snd_pcm_subformat_t *)&val);
printf("subformat = '%s' (%s)/n",
snd_pcm_subformat_name((snd_pcm_subformat_t)val),
snd_pcm_subformat_description(
(snd_pcm_subformat_t)val));
snd_pcm_hw_params_get_channels(params, &val);
printf("channels = %d/n", val);
snd_pcm_hw_params_get_rate(params, &val, &dir);
printf("rate = %d bps/n", val);
snd_pcm_hw_params_get_period_time(params,
&val, &dir);
printf("period time = %d us/n", val);
snd_pcm_hw_params_get_period_size(params,
&frames, &dir);
printf("period size = %d frames/n", (int)frames);
snd_pcm_hw_params_get_buffer_time(params,
&val, &dir);
printf("buffer time = %d us/n", val);
snd_pcm_hw_params_get_buffer_size(params,
(snd_pcm_uframes_t *) &val);
printf("buffer size = %d frames/n", val);
snd_pcm_hw_params_get_periods(params, &val, &dir);
printf("periods per buffer = %d frames/n", val);
snd_pcm_hw_params_get_rate_numden(params,
&val, &val2);
printf("exact rate = %d/%d bps/n", val, val2);
val = snd_pcm_hw_params_get_sbits(params);
printf("significant bits = %d/n", val);
snd_pcm_hw_params_get_tick_time(params,
&val, &dir);
printf("tick time = %d us/n", val);
val = snd_pcm_hw_params_is_batch(params);
printf("is batch = %d/n", val);
val = snd_pcm_hw_params_is_block_transfer(params);
printf("is block transfer = %d/n", val);
val = snd_pcm_hw_params_is_double(params);
printf("is double = %d/n", val);
val = snd_pcm_hw_params_is_half_plex(params);
printf("is half plex = %d/n", val);
val = snd_pcm_hw_params_is_joint_plex(params);
printf("is joint plex = %d/n", val);
val = snd_pcm_hw_params_can_overrange(params);
printf("can overrange = %d/n", val);
val = snd_pcm_hw_params_can_mmap_sample_resolution(params);
printf("can mmap = %d/n", val);
val = snd_pcm_hw_params_can_pause(params);
printf("can pause = %d/n", val);
val = snd_pcm_hw_params_can_resume(params);
printf("can resume = %d/n", val);
val = snd_pcm_hw_params_can_sync_start(params);
printf("can sync start = %d/n", val);
snd_pcm_close(handle);
return 0;
}