zoukankan      html  css  js  c++  java
  • OSS研究

    在以前没有毕业之前,做过了一个了播放器,其实就是mplayer的二次开发。

    如果在这个播放器之上,加个oss作声音输入,那不就可以做个卡拉OK啦?


    1.OSS的定义

    OSS(Open Sound System,开放声音系统),是unix或类unix环境中的音频接口(录音、放音、采样率等的设置),也被称为是一种音频驱动结构。只要音频处理应用程序按照OSS的API来编写,那么在移植到另外一个平台时,只需要重新编译即可。


    2.基础知识

    数字音频设备(有时也称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


    3.音频编程

    OSS为音频编程提供三种设备,分别是/dev/dsp,/dev/dspW和/dev/audio,前面已经提到了它们之间的区别。

    用户可以直接使用Unix的命令来放音和录音,命令cat /dev/dsp >xyz可用来录音,录音的结果放在xyz文件中;命令cat xyz >/dev/dsp播放声音文件xyz。

    如果通过编程的方式来使用这些设备,那么Unix平台通过文件系统提供了统一的访问接口。程序员可以通过文件的操作函数直接控制这些设备,这些操作函数包括:open、

    close、read、write、ioctl等。下面我们就分别讨论打开音频设备、放音、录音和参数调整。


    4.音频录放框架

    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <linux/soundcard.h> 
    
    #define LEN 3    /* 存储秒数 */
    #define RATE 8000   /* 采样频率 */
    #define SIZE 8      /* 量化位数 */
    #define CHANNELS 1 /* 声道数目 */
    
    /* 用于保存数字音频数据的内存缓冲区 */
    unsigned char buf[LEN*RATE*SIZE*CHANNELS/8];
    
    int main()
    {
        int fd; /* 声音设备的文件描述符 */
    	int arg; /* 用于ioctl调用的参数 */
        int status; /* 系统调用的返回值 */
    	
        /* 打开声音设备 */
        fd = open("/dev/dsp", O_RDWR);
        if (fd < 0)
        {
            perror("open of /dev/dsp failed");
            exit(1);
        }
    
        /* 设置采样时的量化位数 */
        arg = SIZE;
        status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    
        if (status == - 1)
            perror("SOUND_PCM_WRITE_BITS ioctl failed");
    
        if (arg != SIZE)
            perror("unable to set sample size"); 
    
        /* 设置采样时的通道数目 */
        arg = CHANNELS;
    
        status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    
        if (status == - 1)
            perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
    
        if (arg != CHANNELS)
            perror("unable to set number of channels"); 
    
        /* 设置采样率 */
           arg = RATE;
    
           status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    
           if (status == - 1)
               perror("SOUND_PCM_WRITE_WRITE ioctl failed");
    
    	/* 循环,直到按下Control-C */
        while (1) 
    	{
    	   printf("Say something:
    ");
    	   status = read(fd, buf, sizeof(buf)); /* 录音 */
    
    	   if (status != sizeof(buf))
    		   perror("read wrong number of bytes");
    
    	   printf("You said:
    ");
    	   status = write(fd, buf, sizeof(buf)); /* 放音 */
    
    	   if (status != sizeof(buf))
    		   perror("wrote wrong number of bytes");
    
    	   /* 在继续录音前等待放音结束 */
    	   status = ioctl(fd, SOUND_PCM_SYNC, 0);
    	   
    	   if (status == - 1)
    		   perror("SOUND_PCM_SYNC ioctl failed");		
    	}
    }

    不知道为什么,录音的声音在虚拟机上变成了滴答声,这个有代考究。


    总结:

    利用oss,加入播放器,配以字幕,一个卡拉OK软件就这样了。


    参考资料:

    Mr.Right的专栏:http://blog.csdn.net/lanmanck/article/details/5818723



  • 相关阅读:
    数据结构——二叉搜索树、B树、B-树
    计算机组成原理——指令流水线
    计算机组成原理——微指令的控制字段
    计算机组成原理——关于数据对齐存储
    program
    数据库——视图(View)相关
    软件测试——性能测试、压力测试、负载测试等详解
    软件测试——Stub和Mock
    虚拟机的性能监控与故障处理工具
    Linux中安装tomcat后,window中访问不到tomcat的欢迎界面问题
  • 原文地址:https://www.cnblogs.com/james1207/p/3347950.html
Copyright © 2011-2022 走看看