zoukankan      html  css  js  c++  java
  • OSS音频编程实例

    虽说现在较新的kernel都支持ALSA了,但是我认为OSS编程是比较容易上手的,因为比较符合Linux的编程的框架。再说ALSA配置的时候也可以选择OSS支持,这样OSS应用程序无需更改就可以使用ALSA驱动。


    关于录音和放音的ADC/DAC的控制设备节点为/dev/dsp, 音量调整的设备节点为/dev/mixer。

    从/dev/dsp读取的过程是录音,向/dev/dsp写入的过程为播放。

    有许多CODEC,不支持以O_RDWR的方式打开。所以对于读和写,要分别打开,以两个文件描述符进行操作。

    针对录音的流程,大致代码如下:

    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <sys/stat.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <linux/soundcard.h>
    
    #define RATE 48000
    #define CHANNELS 2
    #define BITS 16
    #define TOTAL (BITS * RATE * CHANNELS / 8 * 15) //15 seconds
    #define BYTES_4K 4096
    #define RECORD_FILE  "/mnt/disk/record.pcm"
    int main()
    {
    	int pcm_fd;
    	int dsp_fd_rd;
    	char buf[4 * 1024] = {0};
    	int ret = 0;
    	int total = 0;
    
    	int rate = RATE;
    	int channels = CHANNELS;
    	int bits = BITS;
    	
    	dsp_fd_rd = open("/dev/dsp", O_RDONLY);
    
    	if (dsp_fd_rd < 0)
    	{
    		perror("Failed to open!\n");
    		return -1;
    	}
    
    	pcm_fd = open(RECORD_FILE, O_WRONLY | O_CREAT, 0666);
    	if (pcm_fd < 0)
    	{
    		perror("Failed to open/create pcm file");
    		return -1;
    	}
    
    	ioctl(dsp_fd_rd, SNDCTL_DSP_SPEED, &rate);
    	ioctl(dsp_fd_rd, SNDCTL_DSP_STEREO, &channels);
    	ioctl(dsp_fd_rd, SNDCTL_DSP_SETFMT, &bits);
    
    	while (1)
    	{
    		ret = read(dsp_fd_rd, buf, BYTES_4K);
    		if (ret < 0)
    		{
    			perror("Failed to read!");
    			return -1;
    		}
    		if (write(pcm_fd, buf, ret) < 0)
    		{
    			perror("Failed to write!");
    			return -1;
    
    		}
    		total += ret;
    		if (total >= TOTAL)
    			break;
    	}
    
    	return 0;
    }


    成功打开/dev/dsp后,要进行简单的设置,以上代码为了简单起见,没有对ioctl的返回值进行判断。需要设置的有:

    采样频率:这里为48Khz

    通道数:2通道,也就是stereo

    量化位数:16bit


    还有一点要注意的是,针对我们的平台,每次read的大小必须为4K,也就是PAGE_SIZE的大小,因为DMA处理是以页为单位的。

    以上代码实现简单的录音15秒并存放在文件中。


    下面的代码设置了播放音量


    int set_mixer_vol(unsigned int val)
    {
    	int mixer_fd = open("/dev/mixer", O_RDWR);
    	if (mixer_fd < 0)
    	{   
    		perror("Failed to open /dev/mixer!");
    		return -1; 
    	}   
    	else
    	{   
    		if ((val & 0xff) > 100)
    		{   
    			val = 100;
    		}   
    		ioctl(mixer_fd, SOUND_MIXER_WRITE_VOLUME, &val);
    		close(mixer_fd);
    	}   
    
    	return 0;
    }


    这里只是设置了外放的音量,还有好多可以设置的,比如耳机,蓝牙,如果是手机的话,还有听筒。


    播放的代码与录音类似,在此就不贴出了。

  • 相关阅读:
    solr两种启动方式
    Centos7安装Solr
    关于netcore webservice 构建和参数大小控制问题
    百度开源ocr安装(飞浆)
    C# netcore 开发WebService(Soap)
    Aspose.CAD库简介 CAD转换PDF
    .net或JAVAK开发如何实现上传文件夹功能
    【转】TCP和SOCKET关系
    Asp.Net 绑定下拉框的值
    Windwos服务器远程桌面突然不能复制粘贴
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2987533.html
Copyright © 2011-2022 走看看