Chinaunix首页 | 论坛 | 博客
  • 博客访问: 591631
  • 博文数量: 107
  • 博客积分: 713
  • 博客等级: 上士
  • 技术积分: 1050
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-05 00:14
个人简介

呵呵

文章分类

全部博文(107)

文章存档

2015年(2)

2014年(17)

2013年(29)

2012年(52)

2011年(7)

分类: LINUX

2012-10-23 21:07:45

一.准备

移植Madplay所需四个软件包分别为libid3tag-0.15.1b.tar.gz

libmad-0.15.1b.tar.gzzlib-1.1.4.tar.gzmadplay-0.15.2b.tar.gz

 

二.解压

   1mkdir /mp3 建立MP3目录

          2. tar -zxvf libid3tag-0.15.1b.tar.gz -C /mp3

          3. tar -zxvf ibmad-0.15.1b.tar.gz -C /mp3

       4. tar -zxvf zlib-1.1.4.tar.gz -C /mp3

       5. tar -zxvf madplay-0.15.2b.tar.gz -C /mp3

 

三.编译zlib

#cd /mp3/zlib-1.1.4  

#./configure --prefix=/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/lib

     修改Makefile

     AR=/usr/local/arm/4.3.2/bin/arm-linux-ar rcs

     CC=/usr/local/arm/4.3.2/bin/arm-linux-gcc

     RANLIB=/usr/local/arm/4.3.2/bin/arm-linux-ranlib

      

  执行  #make

         #make install

 

四.编译libid3tag

#cd /mp3/libid3tat-0.15.1d

#./configure --host=arm-linux CC=arm-linux-gcc --disable-debugging --disable-shared --prefix=/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/lib

 

     #make

     #make install

 

 

五.编译libmad

#cd /mp3/libmad-0.15.1b  

#./configure --enable-fpm=arm --host=arm-linux --disable-shared --disable-debugging --prefix=/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/lib

修改 Makefile 129 去掉 –fforce-mem

 

     #make

     #make install

 

六.编译madplay

#cd /mp3/madplay-0.15.2b   

#./configure --host=arm-linux CC=arm-linux-gcc --disable-debugging --disable-shared

     #make

     但是,这样得到的是动态连接的。

     #rm madplay

     拷贝make的最后一个连接的命令,在最后加上-static -lz,然后运行,得到静态连接的程序

       

 

arm-linux-gcc -Wall -O2 -fomit-frame-pointer -o madplay madplay.o getopt.o getopt1.o version.o resample.o filter.o tag.o crc.o rgain.o player.o audio.o audio_aiff.o audio_cdda.o audio_hex.o audio_null.o audio_raw.o audio_snd.o audio_wave.o audio_oss.o  -lmad -lid3tag -lm -lz -static

最后把madplay下到板子就可以了.


mplayer移植到mips上

1.下载地址 

2. tar xxvf MPlayer-1.1.tar.xz

cd MPlayer-1.1

3. 修改./configure 文件的

2592 _install_strip="-s"
2592 #_install_strip="-s"
2593 _install_strip=

4./configure –cc=mipsel-unknown-linux-gnu-gcc –prefix=/nfsboot/mips/ –target=mipsel-unknown-linux –as=mipsel-unknown-linux-gun-as –extra-cflags=-march=mips2

make

make  install




应用程序:

/*

 *     mp3播放器控制程序

 *   功能:

  k1:播放、暂停

  k2:停止播放

  k3:上一首

  k4:下一首

 *     附加:歌曲自动循环播放

 *

 */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


/*共享内存申请标记*/

#define PERM S_IRUSR|S_IWUSR


/*双向循环列表:存放歌曲名*/

struct song

{

char songname[20];

struct song *prev;

struct song *next;

};


/*孙子进程id号*/

pid_t gradchild;


/*子进程id号*/

pid_t pid;


/*共享内存描述标记*/

int shmid;


char *p_addr;


/*播放标记*/

int first_key=1;

int play_flag=0;


/*************************************************

Function name: play

Parameter    : struct song *

Description : 播放函数

Return : void

Argument     : void

Autor & date : ada 09,12,07

**************************************************/

void play(struct song *currentsong)

{

pid_t fd;

char *c_addr;

char *p;

int len;

char my_song[30]="/mp3/song/";

while(currentsong)

{

/*创建子进程,即孙子进程*/

fd = fork();

if(fd == -1)

{

perror("fork");

exit(1);

}

else if(fd == 0)

{

/*把歌曲名加上根路径*/

strcat(my_song,currentsong->songname);

p = my_song;

len = strlen(p);


/*去掉文件名最后的'\n'*/

my_song[len-1]='\0';


printf("THIS SONG IS %s\n",my_song);

execl("/mp3/madplay","madplay",my_song,NULL);

printf("\n\n\n");

}

else

{

/*内存映射*/

c_addr = shmat(shmid,0,0);


/*把孙子进程的id和当前播放歌曲的节点指针传入共享内存*/

memcpy(c_addr,&fd,sizeof(pid_t));

memcpy(c_addr + sizeof(pid_t)+1,¤tsong,4);

/*使用wait阻塞孙子进程,直到孙子进程播放完才能被唤醒;

 当被唤醒时,表示播放MP3期间没有按键按下,则继续顺序播放下一首MP3*/

if(fd == wait(NULL))

{

currentsong = currentsong->next;

printf("THE NEXT SONG IS %s\n",currentsong->songname);

}

}

}

}


/*************************************************

Function name: creat_song_list

Parameter    : void

Description : 创建歌曲名的双向循环链表

Return : struct song *

Argument     : void

Autor & date : ada 09.12.07

**************************************************/

struct song *creat_song_list(void)

{

FILE *fd;

size_t size;

size_t len;

char *line = NULL;

struct song *head;

struct song *p1;

struct song *p2;

system("ls /mp3/song >song_list");

fd = fopen("song_list","r");


p1 = (struct song *)malloc(sizeof(struct song));


printf("==================================song list=====================================\n");

system("ls /mp3/song");

printf("\n");

printf("================================================================================\n");

size = getline(&line,&len,fd);


strncpy(p1->songname,line,strlen(line));

head = p1;

while((size = getline(&line,&len,fd)) != -1)

{

p2 = p1;

p1 = (struct song *)malloc(sizeof(struct song));

strncpy(p1->songname,line,strlen(line));

p2->next = p1;

p1->prev = p2;

}

p1->next = head;

head->prev = p1;

p1 = NULL;

p2 = NULL;

system("rm -rf song_list");

return head;

}

/*************************************************

Function name: startplay

Parameter    : pid_t *,struct song *

Description : 开始播放函数

Return : void

Argument     : void

Autor & date : ada 09.12.07

**************************************************/

void startplay(pid_t *childpid,struct song *my_song)

{

pid_t pid;

int ret;

/*创建子进程*/

pid = fork();


if(pid > 0)

{

*childpid = pid;

play_flag = 1;

sleep(1);

/*把孙子进程的pid传给父进程*/

memcpy(&gradchild,p_addr,sizeof(pid_t));

}

else if(0 == pid)

{

/*子进程播放MP3函数*/

play(my_song);

}

}

/*************************************************

Function name: my_pause

Parameter    : pid_t

Description : 暂停函数

Return : void

Argument     : void

Autor & date : ada 09,12,07

**************************************************/

void my_pause(pid_t pid)

{

printf("=======================PAUSE!PRESS K1 TO CONTINUE===================\n");

kill(pid,SIGSTOP); //对孙子进程发送SKGSTOP信号

play_flag = 0;

}


/*************************************************

Function name: my_pause

Parameter    : pid_t

Description : 停止播放函数

Return : void

Argument     : void

Autor & date : ada 09,12,07

**************************************************/

void my_stop(pid_t g_pid)

{


printf("=======================STOP!PRESS K1 TO START PLAY===================\n");

kill(g_pid,SIGKILL); //对孙子进程发送SKGKILL信号

kill(pid,SIGKILL);   //对子进程发送SKGKILL信号

first_key=1;


}


/*************************************************

Function name: conti_play

Parameter    : pid_t

Description : 继续函数

Return : void

Argument     : void

Autor & date : ada 09,12,07

**************************************************/

void conti_play(pid_t pid)

{

printf("===============================CONTINUE=============================\n");

kill(pid,SIGCONT); //对孙子进程发送SIGCONT信号

play_flag=1;

}


/*************************************************

Function name: next

Parameter    : pid_t

Description : 下一首函数

Return : void

Argument     : void

Autor & date : ada 09.12.07

**************************************************/

void next(pid_t next_pid)

{

struct song *nextsong;


printf("===============================NEXT MP3=============================\n");

/*从共享内存获得孙子进程播放歌曲的节点指针*/

memcpy(&nextsong,p_addr + sizeof(pid_t)+1,4);

/*指向下首歌曲的节点*/

nextsong = nextsong->next;

/*杀死当前歌曲播放的子进程,孙子进程*/

kill(pid,SIGKILL);

kill(next_pid,SIGKILL);

wait(NULL);

startplay(&pid,nextsong);

}


/*************************************************

Function name: prev

Parameter    : pid_t

Description : 上一首函数

Return : void

Argument     : void

Autor & date : yuanhui 09.12.08

**************************************************/

void prev(pid_t prev_pid)

{

struct song *prevsong;

/*从共享内存获得孙子进程播放歌曲的节点指针*/

printf("===============================PRIOR MP3=============================\n");

memcpy(&prevsong,p_addr + sizeof(pid_t)+1,4);

/*指向上首歌曲的节点*/

prevsong = prevsong->prev;

/*杀死当前歌曲播放的子进程,孙子进程*/

kill(pid,SIGKILL);

kill(prev_pid,SIGKILL);

wait(NULL);

startplay(&pid,prevsong);

}


/*************************************************

Function name: main

Parameter    : void

Description : 主函数

Return : int

Argument     : void

Autor & date : ada 09.12.07

**************************************************/

int main(void)

{

int buttons_fd;

int key_value;

struct song *head;

/*打开设备文件*/

buttons_fd = open("/dev/buttons", 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 0:

startplay(&pid,head);

first_key=0;

break;

case 1:

case 2:

case 3:

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 0:

//printf("play_flag:%d\n",play_flag);

if(play_flag)

my_pause(gradchild);

else

conti_play(gradchild);

break;

case 1:

my_stop(gradchild);

break;

case 2:

next(gradchild);

break;

case 3:

prev(gradchild);

break;

} //end switch

}//end if(!first_key)


}

}

}


close(buttons_fd);

return 0;

}

驱动程序:


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include


#define DEVICE_NAME     "buttons"


//#define DEBUG 

struct button_irq_desc {

    int irq;

    int pin;

    int pin_setting;

    int number;

    char *name;

};


#if !defined (CONFIG_QQ2440_BUTTONS)

static struct button_irq_desc button_irqs [] = {

    {IRQ_EINT8 , S3C2410_GPG0 ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},

    {IRQ_EINT11, S3C2410_GPG3 ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},

    {IRQ_EINT13, S3C2410_GPG5 ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},

    {IRQ_EINT14, S3C2410_GPG6 ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},

    {IRQ_EINT15, S3C2410_GPG7 ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},

    {IRQ_EINT19, S3C2410_GPG11,  S3C2410_GPG11_EINT19, 5, "KEY5"},

};

#else /* means QQ */

static struct button_irq_desc button_irqs [] = {

    {IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 0, "KEY0"},

    {IRQ_EINT11, S3C2410_GPG3,  S3C2410_GPG3_EINT11,  1, "KEY1"},

    {IRQ_EINT2,  S3C2410_GPF2,  S3C2410_GPF2_EINT2,   2, "KEY2"},

    {IRQ_EINT0,  S3C2410_GPF0,  S3C2410_GPF0_EINT0,   3, "KEY3"},

    {       -1,            -1,                 -1,    4, "KEY4"},

    {       -1,            -1,                 -1,    5, "KEY5"},

};

#endif

//static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};

static int key_values = 0;


static DECLARE_WAIT_QUEUE_HEAD(button_waitq);


static volatile int ev_press = 0;



static irqreturn_t buttons_interrupt(int irq, void *dev_id)

{

    struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;

    int down;

    // udelay(0);

    

    /*上升沿触发,GPIO DAT 应该为非0 的数*/

    down = !s3c2410_gpio_getpin(button_irqs->pin);

    if (!down) { 

//printk("rising\n");

key_values = button_irqs->number;

        ev_press = 1;

        wake_up_interruptible(&button_waitq);

    }

   else {

//printk("falling\n");

ev_press = 0;

return 0;

   }

    return IRQ_RETVAL(IRQ_HANDLED);

}



static int s3c24xx_buttons_open(struct inode *inode, struct file *file)

{

    int i;

    int err = 0;

    

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

if (button_irqs[i].irq < 0) {

continue;

}


  /* 设置中断触发方式 IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH ;我们这里设置为上升沿触发*/

        //err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, 

        //                  button_irqs[i].name, (void *)&button_irqs[i]);

        err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_RISING, 

                          button_irqs[i].name, (void *)&button_irqs[i]);

        if (err)

            break;

    }


    if (err) {

        i--;

        for (; i >= 0; i--) {

   if (button_irqs[i].irq < 0) {

continue;

   }

   disable_irq(button_irqs[i].irq);

            free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

        }

        return -EBUSY;

    }


    ev_press = 0;

    

    return 0;

}



static int s3c24xx_buttons_close(struct inode *inode, struct file *file)

{

    int i;

    

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {

if (button_irqs[i].irq < 0) {

   continue;

}

free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);

    }


    return 0;

}



static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)

{

    unsigned long err;

    //int i=0;

    if (!ev_press) {

if (filp->f_flags & O_NONBLOCK)

   return -EAGAIN;

else

   wait_event_interruptible(button_waitq, ev_press);

    }

    if(count != sizeof key_values)

return -EINVAL;

    ev_press = 0;

    err = copy_to_user(buff, &key_values, sizeof(key_values));

    return sizeof(key_values);

}


static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)

{

    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait);

    if (ev_press)

        mask |= POLLIN | POLLRDNORM;

    return mask;

}



static struct file_operations dev_fops = {

    .owner   =   THIS_MODULE,

    .open    =   s3c24xx_buttons_open,

    .release =   s3c24xx_buttons_close, 

    .read    =   s3c24xx_buttons_read,

    .poll    =   s3c24xx_buttons_poll,

};


static struct miscdevice misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = DEVICE_NAME,

.fops = &dev_fops,

};


static int __init dev_init(void)

{

int ret;


ret = misc_register(&misc);

#ifdef DEBUG

printk("debug test\n");//ykz

#endif

printk (DEVICE_NAME"\tinitialized\n");


return ret;

}


static void __exit dev_exit(void)

{

misc_deregister(&misc);

}


module_init(dev_init);

module_exit(dev_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("FriendlyARM Inc.");






阅读(3832) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~