DSP

OSS(Open Sound System)资料

2019-07-13 19:21发布

OSS的层次结构非常简单,应用程序通过API(定义于 )访问OSS driver,OSS driver控制声卡。 声卡中主要有两个基本装置:Mixer和CODEC(ADC/DAC)。Mixer用来控制输入音量的大小,对应的设备文件为/dev/mixer;CODEC用来实现录音(模拟信号转变为数字信号)和播放声音(数字信号转变为模拟信号)的功能,对应的设备文件为/dev/dsp。
  开发OSS应用程序的一般流程是:
  1)包含OSS头文件:#include
  2)打开设备文件,返回文件描述符
  3)使用ioctl设置设备的参数,控制设备的特性
  4)对于录音,从设备读(read)
  5)对于播放,向设备写(write)
  6)关闭打开的设备
2.缓冲区设置的性能分析
  在设置驱动内部的缓冲区时,存在一个矛盾:在声卡驱动程序中,为了防止抖动的出现,保证播放的性能,设置了内部缓冲区--DMA buffer。在播放时,应用程序通过驱动程序首先将音频数据从应用程序缓冲区-APP buffer,写入到DMA buffer。接着,由DMA控制器把DMA buffer中的音频数据发送到DAC(Digital-Analog Converter)。
    某些时刻CPU非常的繁忙,比如正在从磁盘读入数据,或者正在重画屏幕,没有时间向DMA buffer放入新的音频数据。DAC由于没有输入新的音频数据,导致声音播放的间断,这就出现了声音的抖动现象。     此时,需要将DMA buffer设置的足够大,使得DAC始终有数据播放。但是,DMA buffer的增大使得每次从APP buffer拷贝的时间也变长,导致了更大的播放延迟。这对于那些延迟敏感的应用场合,如与用户有交互的音频应用程序,就会出现问题。
  
  对于这个矛盾,可以从两个不同的方面分别着手解决。驱动程序采用多缓冲(Multi-buffering)的方式,即将大的DMA buffer分割成多个小的缓冲区,称之为fragment,它们的大小相同。驱动程序开始时只需等待两个fragment满了就开始播放。这样可以通过增加fragment的个数来增加缓冲区的大小,但同时每个fragment被限制在合适的大小,也不影响时延。音频驱动程序中的多缓冲机制一般会利用底层DMA控制器的scatter-gather功能。
  
  另一方面,应用程序也可指导驱动程序选择合适大小的缓冲区,使得在没有抖动的情况下,时延尽可能的小。特别的,应用程序将驱动程序中的缓冲通过mmap映射到自己地址空间后,会以自己的方式来处理这些缓冲区(与驱动程序的不一定一致),这时应用程序往往会先根据自己的需要设置驱动程序中内部缓冲区的大小。
  
  在OSS的ioctl接口中,SNDCTL_DSP_SETFRAGMENT就是用来设置驱动程序内部缓冲区大小。具体的用法如下:
  int param;
  param = ( 0x0004 << 16) + 0x000a;
  if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, ¶m) == -1) { 
        ...error handling...
  }
参数param由两部分组成:低16位为fragment的大小,此处0x000a表示fragment大小为2^0xa,即1024字节;高16位为fragment的数量,此处为0x0004,即4个fragement。设置好fragment参数后,通过ioctl的SNDCTL_DSP_SETFRAGMENT命令调整驱动程序中的缓冲区。  基础名词: 数字音频设备(有时也称codec,PCM,DSP,ADC/DAC设备):播放或录制数字化的声音。它的指标主要有:采样速率(电话为8K,DVD为96K)、channel数目(单声道,立体声)、采样分辨率(8-bit,16-bit)。 mixer(混频器):用来控制多个输入、输出的音量,也控制输入(microphone,line-in,CD)之间的切换。 synthesizer(合成器):通过一些预先定义好的波形来合成声音,有时用在游戏中声音效果的产生。 MIDI 接口:MIDI接口是为了连接舞台上的synthesizer、键盘、道具、灯光控制器的一种串行接口。 在Unix系统中,所有的设备都被统一成文件,通过对文件的访问方式(首先open,然后read/write,同时可以使用ioctl读取/设置参数,最后close)来访问设备。在OSS中,主要有以下的几种设备文件:
  • /dev/mixer:访问声卡中内置的mixer,调整音量大小,选择音源。
  • /dev/sndstat:测试声卡,执行cat /dev/sndstat会显示声卡驱动的信息。
  • /dev/dsp 、/dev/dspW、/dev/audio:读这个设备就相当于录音,写这个设备就相当于放音。/dev/dsp与/dev/audio之间的区别在于采样的编码不同,/dev/audio使用μ律编码,/dev/dsp使用8-bit(无符号)线性编码,/dev/dspW使用16-bit(有符号)线形编码。/dev/audio主要是为了与SunOS兼容,所以尽量不要使用。
  • l /dev/sequencer:访问声卡内置的,或者连接在MIDI接口的synthesizer。