int format;
format = AFMT_S16_LE;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
/* fatal error */
perror("SNDCTL_DSP_SETFMT");
exit(1);
}
if (format != AFMT_S16_LE) {
/* 本设备不支持选择的采样格式. */
}
在设置采样格式之前,可以先测试设备能够支持那些采样格式,方法如下:
int mask;
if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &mask) == -1) {
/* Handle fatal error ... */
}
if (mask & AFMT_MPEG) {
/* 本设备支持MPEG采样格式 ... */}
设置通道数目
int channels = 2; /* 1=mono, 2=stereo */
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
/* Fatal error */
perror("SNDCTL_DSP_CHANNELS");
exit(1);
}
if (channels != 2)
{/* 本设备不支持立体声模式 ... */}
设置采样速率
int speed = 11025;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1) {
/* Fatal error */
perror("SNDCTL_DSP_SPEED");
exit(Error code);
}
if ( /* 返回的速率(即硬件支持的速率)与需要的速率差别很大... */ ) {
/* 本设备不支持需要的速率... */
}
音频设备通过分频的方法产生需要的采样时钟,因此不可能产生所有的频率。驱动程序会计算出最接近要求的频率来,用户程序要检查返回的速率值,如果误差较小,可以忽略,但误差不能太大。
三、Mixer编程
对Mixer的控制,包括调节音量(volume)、选择录音音源(microphone,line-in)、查询mixer的功能和状态,主要是通过Mixer设备/dev/mixer的ioctl接口。相应的,ioctl接口提供的功能也分为三类:调节音量、查询mixer的能力、选择mixer的录音通道。下面就分别介绍使用的方法:
下面的mixer_fd是对mixer设备执行open操作返回的文件描述符。
调节音量
应用程序通过ioctl的SOUND_MIXER_READ和SOUND_MIXER_WIRTE功能号来读取/设置音量。在OSS中,音量的大小范围在0-100之间。使用方法如下:
int vol;
if (ioctl(mixer_fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &vol) == -1) {
/* 访问了没有定义的mixer通道... */
SOUND_MIXER_MIC是通道参数,表示读microphone通道的音量,结果放置在vol中。如果通道是立体声,那么vol的最低有效字节为左声道的音量值,接着的字节为右声道的音量值,另外的两个字节不用。如果通道是单声道,vol中左声道与右声道具有相同的值。
查询mixer的能力
int mask;
if (ioctl(mixer_fd, SOUND_MIXER_READ_xxxx, &mask) == -1) {
/* Mixer 的没有此能力... */
}
SOUND_MIXER_READ_xxxx 中的xxxx代表具体要查询的内容,比如检查可用的mixer通道用SOUND_MIXER_READ_DEVMASK;检查可用的录音设备,用SOUND_MIXER_READ_RECMASK;检查单声道/立体声,用SOUND_MIXER_READ_STEREODEVS;检查mixer的一般能力,用SOUND_MIXER_READ_CAPS等等。所有通道的查询的结果都放在mask中,所以要区分出特定通道的状况,使用mask& (1 << channel_no)。
选择mixer的录音通道
首先可以通过SOUND_MIXER_READ_RECMASK检查可用的录音通道,然后通过SOUND_MIXER_WRITE_RECSRC选择录音通道。可以随时通过SOUND_MIXER_READ_RECSRC查询当前声卡中已经被选择的录音通道。
OSS建议把mixer的用户控制功能单独出来形成一个通用的程序。但前提是,在使用mixer之前,首先通过API的查询功能检查声卡的能力。在linux中,就有一个专门的mixer程序--aumix。
四、结束语
前面讨论的是OSS中一些最基本的内容,实际上OSS中还有很多高级的特性,比如在音频编程时十分重要的实时性问题,画面与声音的同步问题,这里都没有介绍。如果读者对这些特性感兴趣的话,可以进一步参考[1]。另外,在[2]中,还可以下载使用OSS接口的样例程序。