madplay播放器——用按键控制音量

本文介绍了一种使用按键控制播放器音量的方法,并提供了基于CentOS 6.7和arm-linux-gcc-4.5.4环境下实现的具体代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今日诗词欣赏:

                           晏殊 《蝶恋花》

  槛菊愁烟兰泣露,罗幕轻寒,燕子双飞去。明月不谙离别苦,斜光到晓穿朱户。

  昨夜西风凋碧树,独上高楼,望尽天涯路。欲寄彩笺兼尺素,山长水阔知何处。

==========================================================================

主机操作系统:Centos 6.7 
交叉编译器环境:arm-linux-gcc-4.5.4 (可通过命令/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc -v查询)
开发板平台: fl2440 
Linux内核版本: linux-3.0 .54

声卡:uda1341(音频编程接口:ALSA)
播放器:madplay

==========================================================================

           之前我们http://blog.youkuaiyun.com/qicheng777/article/details/71082348 一文中实现了用按键控制madplay播放器,但是由于我们的开发板只有四个按键,所以并未添加控制音量的函数,所以,今天我们来编程实现用按键对播放器音量进行控制。

    不同于我们在开发板上用mixer直接设置音量,用程序控制可以实现在播放歌曲的时候随意更改当前音量大小。

 

一、设置音量函数:  

    给函数传一个值voice,这个值就是设置的当前增益。   

void volume(int voice)
{
    int MIX_FD;             //定义文件描述符
    int iLeft = voice;      //左声道增益
    int iRight = voice;     //右声道增益
    int iLevel;
    iLevel = (iRight << 8) + iLeft;   //

    MIX_FD= open("/dev/mixer", O_WRONLY);   //只写方式打开混音器
    if (MIX_FD == -1) {
        perror("Error:open /dev/mixer error");
        exit(1);
    }
    
	/*设置混音通道增益*/
    if (ioctl(MIX_FD, MIXER_WRITE(SOUND_MIXER_VOLUME), &iLevel) == -1) {  
        perror("Error:MIXER_WRITE ioctl failed");
        exit(1);
    }
    
	/*读取混音通道增益*/
    if (ioctl(MIX_FD, MIXER_READ(SOUND_MIXER_VOLUME), &iLevel) == -1) {   
        perror("Error:MIXER_WRITE ioctl failed");
        exit(1);
    } 
    close(MIX_FD);
}
    这个函数很简单,主要是要知道如何通过ioctl来控制mixer混音器,之前也对混音器相关操作进行了总结,可参考:
http://blog.youkuaiyun.com/qicheng777/article/details/71368101     

    

二、修改主函数:

   为了简便,我把之前关于播放器的其他操作(比如暂停,上一曲等等)以及控制音量的函数都封装在一个头文件(hand_play.h)中了,主函数可直接调用。

/*********************************************************************************
 *      Copyright:  (C) 2017 qicheng
 *                  All rights reserved.
 *
 *       Filename:  bbb.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(04/27/2017)
 *         Author:  yangni <497049229@qq.com>
 *      ChangeLog:  1, Release initial version on "04/27/2017 07:49:28 PM"
 *                 
 ********************************************************************************/
#include <stdlib.h>
#include "hand_play.h"

int main(void)
{
    int buttons_fd;
    int key_value;
    struct song *head;

   
    /*初始音量*/
    static int vol=50;   //这里定义了必须是一个静态变量

    volume(vol);
    /*打开设备文件*/
    buttons_fd = open("/dev/button", 0);
    if (buttons_fd < 0) {
        perror("open device buttons");
        exit(1);
    }


  /*创建播放列表*/
    head = creat_song_list();
    printf("===================================OPTION=======================================\n\n\n\n");
    printf("        K1:START/PAUSE     K2:STOP   K3:NEXT      K4:PRIOR\n\n\n\n");
    printf("================================================================================\n");


  /*共享内存:用于存放子进程ID,播放列表位置*/
    if((shmid = shmget(IPC_PRIVATE,5,PERM))== -1)
        exit(1);
    p_addr = shmat(shmid,0,0);
    memset(p_addr,'\0',1024);
    
    
    while(1) 
    {
        fd_set rds;
        int ret;

        FD_ZERO(&rds);
        FD_SET(buttons_fd, &rds);

        /*监听获取键值*/
        ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);
        if (ret < 0) 
        {
            perror("select");
            exit(1);
        }
        if (ret == 0) 
            printf("Timeout.\n");
        else if (FD_ISSET(buttons_fd, &rds))
        {
            int ret = read(buttons_fd, &key_value, sizeof key_value);
            if (ret != sizeof key_value) 
            {
                if (errno != EAGAIN)
                    perror("read buttons\n");
                continue;
            } 
            else
            {
                //printf("buttons_value: %d\n", key_value+1);
                
                /*首次播放,必须是按键1*/
                if(first_key){
                    switch(key_value)
                    {   
                    case KEY_1:
                        startplay(&pid,head);
                        first_key=0;
                        break;
                    case KEY_2:
                    case KEY_3:
                    case KEY_4:
                        printf("=======================PRESS K1 TO START PLAY===================\n");
                        break;
                    default:
                        printf("=======================PRESS K1 TO START PLAY===================\n");
                        break;
                    } //end switch
                }//end if(first_key)
                /*若不是首次播放,则根据不同键值处理*/
                else if(!first_key){
                    switch(key_value)
                    {
                    case KEY_1:
                        //printf("play_flag:%d\n",play_flag);
                        if(play_flag)
                            my_pause(gradchild);
                        else
                            conti_play(gradchild);
                        break;
                    case KEY_2:
                        next(gradchild);
                        break;
                    case KEY_3:
                        /*减小音量*/
                        while(vol>0)
                        {
                            vol-=10;       //每按键一次减10
                            volume(vol);   //调用刚才我们写的函数设置音量
                            break; 
                        }
                        break;
                    case KEY_4:
                       /*增大音量*/
                        while(vol<120)
                        {   
                            vol+=10;
                            volume(vol);   //调用函数
                            break;
                        }
                        break;
                    } //end switch
                }//end if(!first_key)

            }
                
        }
    }

    close(buttons_fd);
    return 0;
}


   主函数中,定义音量的变量一定要是 静态变量,这样才能保证这个值不被重新初始化。然后在while循环中,一定要用break直接跳出函数。



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值