LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 5800|回复: 9

用c语言怎样控制音量?(已解决)

[复制链接]
发表于 2006-1-8 18:18:17 | 显示全部楼层 |阅读模式
如题,谢谢!
发表于 2006-1-8 19:54:34 | 显示全部楼层
system("aumix -v +5");

system("aumix -v -5");
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-1-9 09:47:04 | 显示全部楼层
参考aumix的源码,经多次实验,终于搞定
[php]
#include <sys/soundcard.h>
#include <fcntl.h>
int
main ()
{
  int handle = open ("/dev/mixer", O_RDWR, 0); //O_RDWR:可读可写,O_RDONLY:只读,O_WRONLY:只写
  if (handle == -1)
    {
      perror ("open");
      return -1;
    }

  int leftright = (30 << 8) | (60 & 0xFF); //左Vol=30,右Vol=60
  int result;
  int dev=0; //设备号为:Vol=0,Pcm=4,Spkr=5,Line=6,Mic=7,CD=8,IGam=12,Line1=14,Digital1=17,PhoneIn=20,PhoneOut=21,Video=22

  if (ioctl (handle, MIXER_WRITE (dev), &leftright) == -1)        //写操作
    {
      perror ("write_error");
    }
   
  if (ioctl (handle, MIXER_READ (dev), &result) == -1)    //读操作
    {
      perror ("read_error");
    }
                                                      
  printf ("left Vol = %d\n", result >> 8);     //显示左Volum
  printf ("right Vol=%d\n", result & 0xFF);    //显示右Volum

  close (handle);
  return 0;
}
[/php]
回复 支持 反对

使用道具 举报

发表于 2006-1-9 09:58:33 | 显示全部楼层
不错不错,收获收获
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-1-9 17:07:09 | 显示全部楼层
居然没有发现这个网站,很全面讲述了oss编程:
http://www.oreilly.de/catalog/multilinux/excerpt/ch14-01.htm
各种调节(音量,麦克,。。。):
http://www.oreilly.de/catalog/multilinux/excerpt/ch14-07.htm
设置采样率,采样时间,单双声道,然后循环地从麦克录音,放音:
http://www.oreilly.de/catalog/multilinux/excerpt/ch14-05.htm
更简单的从麦克录音,然后放音:
http://www.oreilly.de/catalog/multilinux/excerpt/ch14-02.htm
回复 支持 反对

使用道具 举报

发表于 2006-9-25 17:14:58 | 显示全部楼层
实际上,用oss api来编程已经过时了,现时的应该转到alsa的libasound2上来。
回复 支持 反对

使用道具 举报

发表于 2006-9-27 16:59:20 | 显示全部楼层
呵呵,又学到新东西了。
回复 支持 反对

使用道具 举报

发表于 2006-10-21 21:16:34 | 显示全部楼层

基于alsa的音量控制代码

[php]
//头文件
#include <alsa/asoundlib.h>
//类定义
class Sound {
  public:
    Sound();
    ~Sound();
    int sound_read();
    void sound_write(int);
  private:
    snd_mixer_t * mixer;
    snd_mixer_elem_t *pcm_element;
};

//初始化-----------------------------------------------------
Sound::Sound()
{
    snd_mixer_open(&mixer, 0);
    snd_mixer_attach(mixer, "default");
    snd_mixer_selem_register(mixer, NULL, NULL);
    snd_mixer_load(mixer);
    //找到Pcm对应的element,方法比较笨拙
    pcm_element = snd_mixer_first_elem(mixer);
    pcm_element = snd_mixer_elem_next(pcm_element);
    pcm_element = snd_mixer_elem_next(pcm_element);
    //
    long int a, b;
    long alsa_min_vol, alsa_max_vol;
    ///处理alsa1.0之前的bug,之后的可略去该部分代码
    snd_mixer_selem_get_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_LEFT, &a);
    snd_mixer_selem_get_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_RIGHT, &b);

    snd_mixer_selem_get_playback_volume_range(pcm_element,
                                              &alsa_min_vol,
                                              &alsa_max_vol);
    ///设定音量范围
    snd_mixer_selem_set_playback_volume_range(pcm_element, 0, 100);
   
}

//读音量值-----------------------------------------------------
int Sound::sound_read()
{
    long ll, lr;
    //处理事件
    snd_mixer_handle_events(mixer);
    //左声道
    snd_mixer_selem_get_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_LEFT, &ll);
    //右声道
    snd_mixer_selem_get_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_RIGHT, &lr);
    return (ll + lr) >> 1;
}

//写入音量-----------------------------------------------------
void Sound::sound_write(int leftright)
{
    //左音量
    snd_mixer_selem_set_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_LEFT,
                                        leftright);
    //右音量
    snd_mixer_selem_set_playback_volume(pcm_element,
                                        SND_MIXER_SCHN_FRONT_RIGHT,
                                        leftright);
}

//退出-----------------------------------------------------
Sound::~Sound()
{
    snd_mixer_close(mixer);
}
[/php]
编译时要加库: -lasound

以上代码参考了xmms
回复 支持 反对

使用道具 举报

发表于 2006-10-22 00:12:16 | 显示全部楼层
dyte兄跟进的好快啊,^_^
回复 支持 反对

使用道具 举报

发表于 2006-10-22 18:12:39 | 显示全部楼层
我看了你的建议,然后就想把gsopcast/qsopcast的mix代码换成alsa了,也是折腾了好几次才搞明白的,先左网上搜,结果只能写,不能读音量,后来偶然查看xmms代码才知道读之前还需要一个事件处理过程:snd_mixer_handle_events(mixer);

现在该代码的这一段:
    //找到Pcm对应的element,方法比较笨拙
    pcm_element = snd_mixer_first_elem(mixer);
    pcm_element = snd_mixer_elem_next(pcm_element);
    pcm_element = snd_mixer_elem_next(pcm_element);
我觉得还不太好,应该有更直接的方法。

你整理的编程精华我觉得应该把所有无关的跟贴去掉才更清晰一些。
另外视频编程部分没加ffmpeg的解码代码,可参考我的以前的贴子(现在找不到了)
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表