linux alsa声卡命令,Linux ALSA声卡介绍及使用

一. 介绍

ALSA 标准是一个先进的linux声音体系。它包含内核驱动集合,API库和工具对Linux声音进行支持。ALSA 包含一系列内核驱动对不同的声卡进行支持,还提供了libasound的API库。用这些进行写程序不需要打开设备等操作,所以编程人员在写程序的时候不 会被底层的东西困扰。与此相反OSS/Free 驱动在内核层次调用,需要指定设备名和调用ioctl。为提供向后兼容, ALSA 提供内核模块模仿 OSS/Free 驱动,所以大多数的程序不需要改动。 ALSA 拥有调用插件的能力对新设备提供扩展,包括那些用软件模拟出来的虚拟设备。 ALSA 还提供一组命令行工具包括  mixer, sound file player 和工具控制一些特别的声卡的特别的作用。

二.ALSA 体系:

ALSA API 被主要分为以下几种接口:

l         控制接口:提供灵活的方式管理注册的声卡和对存在的声卡进行查询。

l         PCM接口:提供管理数字音频的捕捉和回放。

l         原始 MIDI 接口: 支持 MIDI (Musical Instrument Digital Interface), 一种标准电子音乐指令集。 这些 API 提供访问声卡上的 MIDI 总线。这些原始借口直接工作在 The  MIDI 事件上,程序员只需要管理协议和时间。

l         记时接口: 为支持声音的同步事件提供访问声卡上的定时器。

l         音序器接口:一个比原始MIDI接口高级的MIDI编程和声音同步高层接口。它可以处理很多的MIDI协议和定时器。

l         混音器接口:控制发送信号和控制声音大小的声卡上的设备。

三.声卡的缓存和数据的传输:

一块声卡有一个声卡内存用来存储记录的样本。当它被写满时就产生中断。内核驱动就使用DMA将数据传输到内存中。同样地,当在播放时就将内存中的声音样本 使用DMA传到声卡的内存中!

声卡的缓存是环状的,这里只讨论应用程序中的内存结构:ALSA将数据分成连续的片段然后传到按单元片段传输。

四:典型的声音程序结 构:

open interface for capture or playback

set hardware parameters

(access mode, data format, channels, rate, etc.)

while there is data to be processed:

read PCM data (capture)

or write PCM data (playback)

close interface

五.一些例子:

1.显示一些PCM的类型和格式:

#include 

#include 

intmain()

{

std::cout <

std::cout <

for(intval=0; val <= SND_PCM_STREAM_LAST; ++val)

std::cout <

std::cout <

std::cout <

for(intval=0; val <= SND_PCM_ACCESS_LAST; ++val)

std::cout <

std::cout <

std::cout <

for(intval=0; val <= SND_PCM_SUBFORMAT_LAST; ++val)

std::cout <

<

std::cout <

std::cout <

for(intval=0; val <= SND_PCM_STATE_LAST; ++val)

std::cout <

std::cout <

std::cout <

for(intval=0; val <= SND_PCM_FORMAT_LAST; ++val)

std::cout <

<

std::cout <

}

2.打开PCM设备和设置参数

#include 

#include 

intmain()

{

intrc;

snd_pcm_t* handle;

snd_pcm_hw_params_t*params;

unsigned intval, val2;

intdir;

snd_pcm_uframes_t frames;

if( (rc = snd_pcm_open(&handle,"default", SND_PCM_STREAM_PLAYBACK, 0)) 

{

std::cerr <

exit(1);

}

snd_pcm_hw_params_alloca(&params);

snd_pcm_hw_params_any(handle, params);

snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

snd_pcm_hw_params_set_channels(handle, params, 2);

val = 44100;

snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);

if( (rc = snd_pcm_hw_params(handle, params)) 

{

std::cerr <

<

exit(1);

}

std::cout <

<

std::cout <

<

snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *)&val);

std::cout <

<

snd_pcm_hw_params_get_format(params, (snd_pcm_format_t*)(&val));

std::cout <

<

snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val);

std::cout <

snd_pcm_subformat_name((snd_pcm_subformat_t)val) <

<

snd_pcm_hw_params_get_channels(params, &val);

std::cout <

snd_pcm_hw_params_get_rate(params, &val, &dir);

std::cout <

snd_pcm_hw_params_get_period_time(params, &val, &dir);

std::cout <

snd_pcm_hw_params_get_period_size(params, &frames, &dir);

std::cout <(frames) <

snd_pcm_hw_params_get_buffer_time(params, &val, &dir);

std::cout <

snd_pcm_hw_params_get_buffer_size(params, (snd_pcm_uframes_t *) &val);

std::cout <

snd_pcm_hw_params_get_periods(params, &val, &dir);

std::cout <

snd_pcm_hw_params_get_rate_numden(params, &val, &val2);

std::cout <

val = snd_pcm_hw_params_get_sbits(params);

std::cout <

snd_pcm_hw_params_get_tick_time(params, &val, &dir);

std::cout <

val = snd_pcm_hw_params_is_batch(params);

std::cout <

val = snd_pcm_hw_params_is_block_transfer(params);

std::cout <

val = snd_pcm_hw_params_is_double(params);

std::cout <

val = snd_pcm_hw_params_is_half_duplex(params);

std::cout <

val = snd_pcm_hw_params_is_joint_duplex(params);

std::cout <

val = snd_pcm_hw_params_can_overrange(params);

std::cout <

val = snd_pcm_hw_params_can_mmap_sample_resolution(params);

std::cout <

val = snd_pcm_hw_params_can_pause(params);

std::cout <

val = snd_pcm_hw_params_can_resume(params);

std::cout <

val = snd_pcm_hw_params_can_sync_start(params);

std::cout <

snd_pcm_close(handle);

return0;

}

3.一个简单的声音播放程序

#include 

#include 

intmain()

{

longloops;

intrc;

intsize;

snd_pcm_t* handle;

snd_pcm_hw_params_t* params;

unsigned intval;

intdir;

snd_pcm_uframes_t frames;

char* buffer;

if( (rc = snd_pcm_open(&handle,"default"

, SND_PCM_STREAM_PLAYBACK, 0)) 

{

std::cerr <

exit(1);

}

snd_pcm_hw_params_alloca(&params);

snd_pcm_hw_params_any(handle, params);

snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);

snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE);

snd_pcm_hw_params_set_channels(handle, params, 2);

val = 44100;

snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir);

frames = 32;

snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir);

if( (rc = snd_pcm_hw_params(handle, params)) 

{

std::cerr <

exit(1);

}

snd_pcm_hw_params_get_period_size(params, &frames, &dir);

size = frames * 4;

buffer = newchar[size];

snd_pcm_hw_params_get_period_time(params, &val, &dir);

loops = 5000000 / val;

while(loops > 0) {

loops--;

if( (rc = read(0, buffer, size)) == 0)

{

std::cerr <

break;

}

elseif(rc != size)

std::cerr <

if( (rc = snd_pcm_writei(handle, buffer, frames)) == -EPIPE)

{

std::cerr <

snd_pcm_prepare(handle);

}

elseif(rc 

std::cerr <

elseif(rc != (int)frames)

std::cerr <

}

snd_pcm_drain(handle);

snd_pcm_close(handle);

free(buffer);

return0;

}

(poseidonqiu)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值