为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

mp3播放器设计论文

2017-11-23 48页 doc 205KB 47阅读

用户头像

is_321575

暂无简介

举报
mp3播放器设计论文mp3播放器设计论文 . 毕 业 设 计(论 文)报 告 (校内实习使用) 2012年10月20 日 — 2013年6月1日 系 别: 计科系 专业班级: 嵌入式二班 学 号: 学生姓名: 指导教师: . . 摘 要 二十一世纪是信息技术的时代,信息的交流量非常大,这就会使人们在计算机面前工作的时间大大增加,因而增加了人们的负担和压力。再加上飞快的生活节奏,物质生活的逐步改善,更会给人们带来身心的劳累,人们在这种身体状况下去工作,不但效率不高,而且还很容易犯错,人们对精神层面的需求逐渐增强。因此人们需...
mp3播放器设计论文
mp3播放器设计论文 . 毕 业 设 计(论 文)报 告 (校内实习使用) 2012年10月20 日 — 2013年6月1日 系 别: 计科系 专业班级: 嵌入式二班 学 号: 学生姓名: 指导教师: . . 摘 要 二十一世纪是信息技术的时代,信息的交流量非常大,这就会使人们在计算机面前工作的时间大大增加,因而增加了人们的负担和压力。再加上飞快的生活节奏,物质生活的逐步改善,更会给人们带来身心的劳累,人们在这种身体状况下去工作,不但效率不高,而且还很容易犯错,人们对精神层面的需求逐渐增强。因此人们需要一些娱乐和消遣的软件来减轻压力,消除疲劳,让人们更好的去工作和生活。由于不满足于仅在家中欣赏电视提供的多媒体,便携的媒体播放器应运而生。本Mp3播放器就是为了实现这个目的而编写的。 由于嵌入式Linux操作系统功能强大又易于移植。本次设计的是MP3播放器应用程序,就是一个基于嵌入式开发的一个媒体播放器软件,采用嵌入式ARM9经典开发平台。 关键词: 嵌入式系统,Linux,Mp3播放器 . . Abstract The twenty-first century is the era of information technology, information exchange is very large, which make people work in front of the computer time is greatly increased, thus increasing the people's burden and pressure. Coupled with the fast pace of life, the gradual improvement of material life, but also give rise to physical and mental fatigue, physical condition in which people go to work not only inefficient, and very easy to make mistakes, people on the spiritual demand gradually. So people need some entertainment and recreation software to reduce stress, reduce fatigue, allow people to work and live better. Because not content to provide only watch TV at home, multimedia, portable media players have emerged. Due to the embedded Linux operating system, powerful and easy to transplant. The design of the MP3 player application, is a development based on an embedded media player software, using the classical embedded ARM9 development platform. Key Words: Embedded systems, Linux, Mp3 player . . 目 录 引 言 ............. 错误~未定义书签。I错误~未定义书签。I错误~未定义书签。I 第1章 绪论 ............................................................ - 3 - 1.1 开发嵌入式MP3播放系统的目的 ....................................... - 5 - 1.2 开发嵌入式MP3播放系统的意义 ....................................... - 5 - 第2章系统及嵌入式LINUX环境的搭建 .................................. - 6 - 2.1嵌入式系统方案的设计 ............................................... - 6 - 2.2 嵌入式LINUX环境的搭建 .............................................. - 6 - 第3章 硬件开发平台及其操作系统的构建 ................................... - 7 - 3.1开发平台的硬件资源 ................................................. - 7 - 9 - 3.2 开发平台的体系结构 ................................................. -3.3 开发平台硬件间的工作流程 .......................................... - 10 - 3.4 开发平台操作系统的搭建 ............................................ - 11 - 3.4.1 U-Boot的编译 ............................................. - 11 - 3.4.2烧写U-boot ............................................... - 12 - 3.4.3 内核(kernel)的编译与烧写 ............................... - 12 - 3.4.4 根文件系统的制作 ......................................... - 13 - 第四章 MP3播放器的制作与移植 ........................................ - 15 - 4.1 MADPLAY原理 ........................................................ - 15 - 4.2移植到TX2440开发板上 ............................................. - 15 - 4.2.1 编译文件 ................................................. - 15 - 4.2.2移植madplay到TX2440 ..................................... - 16 - 结束语..................................................................-13- 致 谢 ..................................................................... 18 参考文献 ................................................................... 20 附 录 ....................................................................16 . . 引 言 我本次的毕业设计论文主要有两个目的:一是对我大学三年专业知识的整合和完成毕业应有的毕业设计论文。二是当今社会人们的工作生活压力非常大而且时间非常的紧张,心理学家经研究后发现听歌可以让人放松,由于现在人们的生活节奏快没有很多单独的时间去唱歌听歌,所以我这次毕业设计设计便携式MP3方便人们随时都能听到优美的音乐从而来放松自己。由于我的专业是嵌入式所以我打算把MP3镶嵌到我们的汽车、手机、机器人等各种设备中方便人们在各种地方都方便听音乐来放松自己。 因为嵌入式Linux操作系统功能强大又易于移植,所以我本次设计的是MP3播放器应用程序,就是一个基于嵌入式ARM9开发的一个媒体播放器软件,采用S3C2440经典开发平台,基于嵌入式ARM9开发的。本软件所具有的功能就可以满足一般用户的要求。本软件能支持所有MP3的音频文件,这些文件在网上都很容易找得到。根据个人的不同喜好,可以下载自己喜欢的MP3歌曲类型进行播放。因为音乐能使人们的神经放松,消除疲累,使人们有更好的状态工作和生活。 . . 第1章 绪论 1.1 开发嵌入式MP3播放系统的目的 二十一世纪是信息技术的时代,信息的交流量非常大,这就会使人们在计算机面前工作的时间大大增加,因而增加了人们的负担和压力。再加上飞快的生活节奏,物质生活的逐步改善,更会给人们带来身心的劳累,人们在这种身体状况下去工作,不但效率不高,而且还很容易犯错,人们对精神层面的需求逐渐增强。因此人们需要一些娱乐和消遣的软件来减轻压力,消除疲劳,让人们更好的去工作和生活。由于不满足于仅在家中欣赏电视提供的多媒体,便携的媒体播放器应运而生。 1.2 开发嵌入式MP3播放系统的意义 社会信息化、智能化、网络化高速发展的今天,嵌入式系统技术也随之提高,嵌入式Linux操作系统功能强大又易于移植,嵌入式产品渗入各个行业,如图1-1所示。嵌入式系统开发无疑成为当今最热门最有发展前途的IT领域之一。 图1-1嵌入式产品渗入各个行业 由于嵌入式Linux操作系统功能强大又易于移植。本次设计的是MP3播放器应用程序,就是一个基于嵌入式ARM9开发的一个媒体播放器软件,采用S3C2440经典开发平台,基于嵌入式ARM9开发的。本软件所具有的功能就可以满足一般用户的要求。本软件能支持所有MP3格式的音频文件,这些文件在网上都很容易找得到。根据个人的不同喜好,可以下载自己喜欢的MP3歌曲类型进行播放。因为音乐能使人们的神经放松,消除疲累,使人们有更好的状态工作和生活。 . . 第2章系统方案及嵌入式Linux环境的搭建 2.1嵌入式系统方案的设计 嵌入式系统开发环境建立在一台主机(pc)上,开发是使用主机上的交叉编译、汇编及连接工具形成在目标板上可以运行的二进制代码。然后下载到板子上运行。本设计的宿主机Linux 操作系统是建立在Linux----Red Hat 9.0虚拟机中,这样可以灵活的与我们熟悉的Windows操作系统进行数据共享,加快开发速度。之后在宿主机上设置各种环境变量,建立交叉编译调试的环境,移植到开发板。 2.2 嵌入式Linux环境的搭建 嵌入式Linux(Embedded Linux)是指对Linux经过小型化裁剪后,能够固化在容量只有几十万字或几十字节的存储器芯片或单片机中,应用于特定嵌入式场合的专用Linux 操作系统。通常它的体积小,性能稳定,源代码免费,将大大减少开发商的成本,更具市竟争力。 最基本的嵌入式Linux系统需要4个基本元素:(1)u-boot移植:包括固化在固件中的启动代码和Bootloader 两大部分,用于完成机器加电后的系统定位引导。(2)LINUX 系统内核的编译和烧写:为嵌入式应用提供一个软件环境,为应用程序完成基本的底层的资源管理工作。(3)根文件系统的制作: 操作系统中负责管理和存储文件信息的软件机构。(4)为了最小嵌入式系统具有一定的实用性,还需加上硬件驱动程序及一个或几个应用进程以提供必要的应用功能支持。 . . 第3章 硬件开发平台及其操作系统的构建 3.1开发平台的硬件资源 我们采用的硬件开发平台为S3C2440经典开发平台。 (1) 核心板 S3C2440 核心板:S3C2440 ARM CPU、64M SDRAM、64M NAND FLASH,通过280Pin 精密插座与主板连接。核心板上可以配置2M 或4M 容量的Nor Flash AM29LV160/320,硬件支持从NorFlash 启动并可增加NandFlash 容量。 PXA270 核心板:PXA270 XScale CPU、64M SDRAM、64M NAND FLASH,16M Nor FLASH。经典平台的核心板接口设计完全兼容博创的 PXA270 核心板和S3C2440 核心板,在软件支持下,两个核心板在经典开发平台主板上均可以实现大部分硬件功能,完全可以替换原有的2440-S 和270A 系列产品。 (2) 双100M EtherNet 网卡:由两片DM9000AE 构成的双网卡,一般可只用其一。 (3) 4 HOST / 1 DEVICE USB 接口:从CPU 的主USB 口扩展为4 个,由AT43301 构成USB HUB。USB 从口保持处理器本身的1 个。 (4) 3 UART/IrDA: 2 个RS232 串口。另有1 个RS485 串口,1 个IrDA 收发器,均从处理器的UART2 引出,由CPLD 内部逻辑进行选择。 (5) 168Pin EXPORT:提供一个168Pin 扩展卡插槽,引出所有总线信号和未占用资源。 (6) LCD 和VGA 接口:标配8 寸16bit 真彩屏,同时预留一个24bit 接口。扩展了VGA 接口和AV 接口,可以连接VGA 显示器。 (7) TouchScr:采用2440 内部ADC 构成的控制和转换电路,或者PXA270 的AC97 CODEC 芯片的触摸屏控制器,二者根据核心板的不同由软件设置CPLD 逻辑进行选择。 和UCB1400,二者根据核心板的不同由软件设置CPLD (8) AUDIO:CODEC 采用UDA1341 逻辑进行选择,具有放音、录音和线路输入等功能。功放电路由LM386 构成,板载扬声器可播放音频。 (9) PS2 KEYPAD:使用ATMEGA8 单片机控制2 个PS2 接口和板载17 键小键盘。两个PS2 可接PC 键盘和鼠标。 (10) LED:扩展2 个数码管和1 个8x8 点阵发光管显示器,均由CPLD 逻辑驱动。 (11) POWER SUPPLY、RESET、RTC 等必须资源。经典平台主板集成了UP-LINK 调试电路,可以直接用并口电缆连接计算机进行仿真、下载等 . . (12) ADC:板载3 个电位器,同时在板上设模拟电压输入专用接口。 (13 )IDE/CF 卡插座:扩展有笔记本硬盘接口和PCCARD 模式的CF 卡接口电路,使用CPLD 芯片实现 PCCARD 逻辑。 (14) SD 卡插座:从CPU 扩展SD 接口。 (15) IC 卡。也由ATMEGA8 单片机控制。 (16) 直流电机。扩展直流电机驱动电路,由PWM 控制。带有红外线测速电路。 (17) CAN BUS:设置1 个CAN 口,采用MCP2510 和TJA1050 芯片构成。 (18) DA 输出:采用MAX504 ,SPI 总线操作,输出模拟电压。 (19) 设置了PWM DA、IIC 存储器、IO 控制LED 和可产生硬中断的按键等简单调试资源 (20) 可以提供配套的GPRS/GPS、FPGA、WLAN、USB2.0、RFID、指纹识别等扩展板。 . . 3.2 开发平台的体系结构 S3C2440开发平台的体系结构如图1-2所示。 图1-2 体系结构. . 3.3 开发平台硬件间的工作流程 S3C2440开发平台的工作流程如图1-3所示。 图1-3 工作流程. . 3.4 开发平台操作系统的搭建 3.4.1 U-Boot的编译 在 U-boot 的board 目录下就是其支持的开发板,数量非常多。这里我们选择2440开发板。 (1) 在board 下建立开发板目录,修改Makefile 文件,添加我们自己开发板的配置信息:在 Makefile 中找到TX2410的配置信息,在下面加上与TX2440 相关的信息 (2) 建立开发板的头文件TX2440.h, 再把所有的文件全部删除,只留TX2440.h,用以下命令建立TX2440.h: cp include/configs/TQM866M.h include/configs/Giga_Switch.h (3) 建立TX2440 开发板的私有目录,即把TX2410目录下的所有文件拷贝到TX2440目录下,包括Makefile. (4) 设置编译工具,我们使用的是3.4.1版本,所以要在Makefile 文件里做相应的修改:将 ifeq($(ARCH),PPC)CROSS_COMPILE = powerpc-linux-修改为: ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- (5) 执行make。 如果可以完成u-boot 编译的全过程,说明TX2440 移植框架成功建立。但是显然现在编译生成的这个U-boot.bin 仍然不适合我们的开发板,实际上它还是为TX2410 开发板设计的源代码。结合具体开发板修改文件,一般来说,虽然U-boot 可以支持很多开发板,但是在开发时有些文件还是要注意结合开发板的具体信息来修改,以下是需要注意修改的几个地方。 SDRAM 的设置:在board/TX2440/lowlevel_init.S中,检查#define B6_BWSCON (DW32) 位宽为32根据HCLK设置SDRAM 的刷新参数,主要是REFCNT寄存器。开发板HCLK为100M将 #define REFCNT 0x1113 改为#define REFCNT 0x4f4,将FCLK设为400MHz,分频比为FCLK:HCLK:PCLK=1:4:8。修改board/TX2440/TX2440.c中的board_init函数,在程序开头增加一行DECLARE_GLOBAL_DATA_PTR;,这样才可以使用gd变量,修改get_PLLCLK函数. 支持NAND Flash:首先在配置文件include/configs/TX2440.h的宏CONFIG_COMMANDS中增加CFG_CMD_NAN,再在include/configs/TX2440.h的最后面增加3个宏。其次 board_nand_init函数定义, board_nand_init需要自己编写,在cpu/arm920t/s3c24x0下新建nand_flash.c编写之前,需要针对S3C2440 NAND Flash定义一些数据结构和函数,. . 在include/s3c24x0.h中增加S3C2440_NAND数据结构,定义2440的函数: static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void) { return (S3C2440_NAND * const)S3C2410_NAND_BASE; } 在cpu/arm920t/s3c24x0/nand_flash.c 中添加代码,是从Linux-2.6.13中/drivers/mtd/nand/s3c2410.c中移植过来的。修改cpu/arm920t/s3c24x0/Makefile: COBJS = 加上一项nand_flash.o 支持网卡芯片DM9000:在driver下,有网卡驱动DM9000x.c 和 DM9000x.h,网卡芯片DM9000接在BANK4,位宽16。在include/configs/TX2440.h中设置网卡的基地址,在drivers目录下,只留nand、nand_legacy、dm9000x.c、dm9000x.h和Makefile文件,其他文件全部删除,修改Makefile文件,将顶层目录下没用的lib_x 文件夹删除,只留lib_arm和lib_generic文件。然后,设置一下Linux启动参数就可以了。 运行执行make TX2440_config make all 生成生成支持NAND Flash和网卡芯片DM9000的u-boot.bin文件。 3.4.2烧写U-boot 将编译后生成的u-boot.bin文件烧入NAND Flash中运行。 3.4.3 内核(kernel)的编译与烧写 我们在网上下载内核源码并解压源码,进入目录linux-2.6.31,修改Makefile文件:指定系统硬件架构、交叉编译器、修改时钟和修改机器码(根据实际情况,这个要和bootloader的匹配)。接下来配置文件,在配置菜单中选择这一项:“Load an Alternate Configuation File”输入2440的默认配置: arch/arm/configs/s3c2410_defconfig 配置完后,回到主菜单,选择这一项“save an Altenate configuration File” 输入要保存的配置文件名称:.config(默认),编译内核:#make zlmage。编译后,会在arch/arm/boot下生成zimage内核镜像文件,把zimage镜像烧进nandflash跑一下,检查是否正常打印出信息。 支持NandFlas h:修改arch/arm/plat-s3c24xx/common-smdk.c文件,这里我们要使nandflash同时支持64M,256M或更高容量。 接下来修改Nand读写匹配时间,这个改不改应该问题都不大,是根据Nand的读写特性相关的,也就是查芯片资料得到的值,每种Nand的值都不一样,修改Kconfig文件,在配置时选择NAND类型,修改driver/mtd/nand/Kconfig, 配置内核,支持NandFlash 。 . . 启动时输出: S3C24XX NAND Driver, (c) 2004 Simtec Electronics s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns s3c24xx-nand s3c2440-nand: NAND hardware ECC NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit) Scanning device for bad blocks Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit": 0x000000000000-0x000000100000 : "boot" 0x000000120000-0x000000520000 : "kernel" 0x000000520000-0x000010000000 : "yaffs2" 支持yaffs2文件系统:下载yaffs2源码并解压,进入yaffs2目录, 给内核打上yaffs2文件系统的补丁,这时内核源码fs目录下多了一个yaffs2目录,同时Makefile文件和Kconfig文件也增加了yaffs2的配置和编译条件。 配置对yaffs2支持这部分配置比较多,可根据自己的需要进行配置,把不用的文件系统都去掉就可以了。 支持LCD:内核里已经有很完善的LCD驱动了,只要根据所用的LCD进行简单的修改,在内核源码drivers/video/s3c2410fb.c是LCD驱动的源码,首先要设置LCD的时钟频率, 在s3c2410fb_display结构体中加入了setclkval变量,我们需要在结构体原型中加入这个变量,在arch/arm/mach-s3c2410/include/mach/fb.h中第40行加入:unsigned setclkval; /*clkval*/ 修改LCD参数配置并屏蔽掉第150行的语句,配置内核,支持LCD。 支持声卡:(1)在网上下了一个uda1341的驱动文件s3c2440-uda1341.c稍作修改后,把它放到linux2.6.14/sound/oss/目录下。(2) 修改oss目录下的kconfig文件,以便在我们下面配置内核的时候可以选中它。(3) 修改Makefile文件,修改增加内存映射,以使内核知道该虚拟地址可用,而且对应的物理地址是我们的声卡。修改 /arch/arm/mach-s3c2410/smdk-s3c2410。(4)配置完毕后,在make menuconfig后,选择driver->sound->oss->uda1341 ,即选择对声卡的支持。 3.4.4 根文件系统的制作 创建根文件系统目录:/bin,/etc,/dev,/home,/lib,/mnt,/pot,/proc,/root,/sbin, /sys,/tmp,/usr,/var 建一个名为root_2.6.31,在文件夹下创建以上目录。编译 busybox,修改 Makefile 文件,执行#make menuconfig进行配置busybox,配置选项大部. . 分都是保持默认的。然后执行 #make make install就会在上一级目录下生成rootfs文件夹,里包含几个文件/bin/sbin/usr/linuxrc把这些文件全部复制到刚建好的root_2.6.31目录下,用命令 #cp –rf * ../root_2.6.31实现。接下来开始制作文件系统,在 dev目录下,创建设备节点,进入etc目录,添加文件:拷贝Busbox-1.15.2/examples/bootfloopy/ etc/*和/etc/passwd,/etc/group,/etx/shadow到当前目录下。修改inittab、fstab 、init.d/rcS和profile文件内容。新建sysconfig 文件夹,在里面新建HOSTNAME文件,内容为:TX2440A 进入lib目录,然后拷贝交叉编译的库文件到lib目录下,文件系统的框架已经做好。把制作好的文件系统烧写进Nandflash中的yaffs2镜像文件。我们使用编译好的mkyaffs2image工具,把解压出来的可执行文件复制到/usr/bin目录下。最后制作文件系统镜像,root_2.6.31bin就是yaffs2文件系统镜像,要先修改它的权限,否则该文件无法被复制,把root_2.6.31.bin下载到nandflash中的文件系统分区中如果文件系统能正常挂载,终端会打印出: Please press Enter to activate this console. Processing/etc/profile „ Done . . 第四章 MP3播放器的制作与移植 4.1 Madplay原理 madplay 是linux上的一个开源mp3播放器,是一个高精度MPEG音频解码库。支持MPEG-1 Layer I, Layer II 和 LayerIII(也就是 MP3),它利用libmad库进行mp3软解码。libmad提供 24-bit 的 PCM 输出,完全定点计算,使用 libmad 提供的一系列 API,就可以非常简单地实现 MP3 数据解码工作。在 libmad 的源代码文件目录下的 mad.h 文件中,可以看到绝大部分该库的数据结构和 API 等。madplay基于libmad还做了一些扩展功能,比如将mp3格式转成别的音频格式如 wav等,又集成了libid3tag库进行mp3信息显示,非常适合在没有浮点支持的嵌入式硬件平台上使用。libmad主要数据结构如表4-1所示: 表4-1 libmad主要数据结构 主要数据结构 作用 struct mad_stream 存放解码前的Bitstream数据 struct mad_synth 存放解码合成滤波后的PCM数据 定义了音频的采样率,声道个数和PCM采样数据, struct mad_pcm 用来初始化音频 记录MPEG帧解码后PCM数据的数据结构,其中的 mad_Header用来记录MPEG帧的基本信息,比如MPEG struct mad_frame 层数、声道模式、流比特率、采样比特率。声道模式包 括单声道、双声道、联合立体混音道以及一般立体声。 4.2移植到TX2440开发板上 4.2.1 编译文件 我们需要在home下先建立两个文件夹,一个存放源码,一个存放安装文件,即madplay-src和madplay 文件夹。依次解压四个源码包到madplay-src目录下。 (1) 编译zlib-1.1.4 使用命令./configure --prefix=/home/madplay进入madplay目录。配置configure . . 文件并修改Makefile 文件中的内容: CC=arm-linux-gcc AR=arm-linux-ar rc RANLIB=arm-linux-ranlib #make #make install (2) 编译libid3tag #./configure CC=arm-linux-gcc --host=arm-linux --prefix=/home/madplay CPPFLAGS=-I/home/madplay/include LDFLAGS=-L/home/madplay/lib #make #make install (3) 编译libmad #./configure CC=arm-linux-gcc --host=arm-linux --prefix=/home/madplay CPPFLAGS=-I/home/madplay/include LDFLAGS=-L/home/madplay/lib #make #make install (4) 编译madplay #./configure CC=arm-linux-gcc --host=arm-linux --prefix=/home/madplay CPPFLAGS=-I/home/madplay/include LDFLAGS=-L/home/madplay/lib #make (5)静态编译 以上是用动态编译的方法,程序运行时需依赖动态库文件。也可以采用静态编译的方 法,将静态库编译到程序中,运行时不需要动态库文件。在配置libid3tag、libmad、madplay 时,加上参数“—disable-shared --enable-static”即可静态编译madplay 。编译完成 后只需将madplay复制到根文件系统/usr/bin目录下,不需要复制动态库。 4.2.2移植madplay到TX2440 编译完成后在madplay-0.15.2b目录下生成madplay的可执行文件,需要的动态库有 libmad.so.0、libid3tag.so.0、libm.so.6和libc.so.6四个库。查看/usr/lib目录中 有没有 libm.so.6和libc.so.6库文件,如果没有,则将其拷贝到/usr/lib目录下。 libmad.so.0和libid3tag.so.0文件是在/madplay/lib/下生成的,也需要拷贝到/usr/lib 下。 最后,将madplay也复制到根文件系统/usr/bin目录下,找一个MP3文件也放在某 一目录下,在开发板上执行madplay程序 #madplay XXX.mp3 MPEG Audio Decoder 0.15.2 (beta) - Copyright (C) 2000-2004 Robert Leslie et al . . s3c2440-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66 Title: XX Artist: XXX Album: XXXX Track: XX Comment: XXXXXXXXX s3c2440-uda1341-superlp: audio_set_dsp_speed:44100 prescaler:66 . . 结束语 开发嵌入式MP3的价值在于它的可移植性强,可以将MP3镶嵌到各个产品和各个行业从而解决了产品的单一化和提高了产品的商业价值。 此款MP3是在嵌入式Linux环境下搭建的。这样的好处在于嵌入式系统开发环境建立在一台主机(pc)上,开发是使用主机上的交叉编译、汇编及连接工具形成在目标板上可以运行的二进制代码。然后下载到板子上运行。本设计的宿主机Linux 操作系统是建立在Linux----Red Hat 9.0虚拟机中,这样可以灵活的与我们熟悉的Windows操作系统进行数据共享,加快开发速度。之后在宿主机上设置各种环境变量,建立交叉编译调试的环境,移植到开发板。 此款MP3在于便于移植,能够固化在容量只有几十万字或几十字节的存储器芯片或单片机中,应用于特定嵌入式场合的专用Linux 操作系统。通常它的体积小,性能稳定,源代码免费,将大大减少开发商的成本,更具市竟争力。但是略感遗憾的是除了选择歌曲和显示歌名外,此播放器没有诸如随意弹奏乐曲、乐曲节奏跳动等功能。而随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一。要为现代人工作、生活提供更好的更方便的服务就需要从单片机技术着手,一切向着数字化控制、智能化控制方向发展。 . . 致 谢 这次毕业设计得到了很多老师、同学的帮助。其中我的指导教师董祥千老师对我的关心和支持尤为重要,每次遇到难题,我最先做的就是向董老师寻求帮助,而董老师每次不管忙或闲,总会抽空来找我面谈,然后一起商量解决的。 另外,感谢校方给予我这样一次机会,能够独立地完成一个课题,并在这个过程当中,给予我们各种方便,使我们在即将离校的最后一段时间里,能够更多学习一些实践应用知识,增强了我们实践操作和动手应用能力,提高了独立思考的能力。 最后再一次对我的母校表示感谢,再一次感谢所有在这次毕业设计中给予过我帮助的人,同时也感谢学院为我提供良好的做毕业设计的环境。以及在设计中被我引用或参考的论著的作者。感谢在整个毕业设计期间和我密切合作的同学,和曾经在各个方面给予过我帮助的伙伴们,在大学生活即将结束的最后的日子里,我们再一次演绎了团结合作的童话,把一个庞大的,从来没有上手的课题,圆满地完成了。 . . 参考文献 [1]陈亮,裴海龙,伍越. 基于Linux系统的USB摄像头视频播放实现[J]. 现代电子技术, 2008(24):93-98. [2]罗贤全,尚朝轩,高勤.开发Linux嵌入式应用程序. 微计算机信息[J](测控自动化), 2004,20(6):67-68. [3]潘影波,王健,Rusty Lynch. MIDLinux新一代播放器的设计与实现[J]. 计算机技术与发 展,2009,19(2):202-204. [4]杜春雷(arm体系结构与编程[M](北京:清华大学出版社(2004 [5]W.Richard Stevens, Stephen A. Rago. Unix Programming in the UNIX Environment 2nd edition[M].译者(尤晋元, 张亚英, 戚正伟),译.北京:人民邮电出版社,2006:47-68. [6]Wim Taymans, Steve Baker, Andy Wingo, Ronald S. Bultje, and Stefan Kost. GStreamer Application Development Manual (0.10.21.3)[M]. Open Publication License. 2009. [7]Jon Masters, Richard Blum. Professional Linux Programming[M]. Wiley Publishing, Inc. 2007:319-340. . . 附 录 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define IDM_FILE 1000 . . #define IDM_OPENFILE 1001 #define IDM_ADDFILE 1002 #define IDM_HELP 1003 #define IDM_ABOUT 1004 #define IDM_EXIT 1005 #define IDC_HELP_ABOUT 1006 #define IDC_ABOUT_BUT 1007 #define IDC_PLAY 1008 #define IDC_PAUSE 1009 #define IDC_CONT 1010 #define IDC_PREV 1011 #define IDC_NEXT 1012 #define IDC_LISTVIEW 1013 #define IDC_TRACKBAR 1014 #define IDM_LIST 1015 #define IDM_OPENLIST 1016 #define IDM_SAVELIST 1017 #define WORD 100 typedef struct list_node{ char file[WORD]; struct list_node *next; struct list_node *prev; }node, *pnode; pnode head = NULL; pnode tail = NULL; . . pnode node_tmp; FILEDLGDATA pfdd; //指定初始化数据及用户选择的文件信息 static int id_child; //子进程 static int id_tmp; //孙子进程 int key_count; static int count; //mp3文件个数 static HWND hListView; //列表句柄 /*表头数据*/ static char* capion[]= { "artist", "title", "year", "genre", "track" }; id3_text_content* artist; id3_text_content* title; id3_text_content* year; id3_text_content* genre; id3_text_content* track; /*获取ID3信息并存入相应变量*/ static void getid3(char file[]) { id3_tag_list *taglist; id3_content *content; taglist = mp_get_tag_list_from_file(file); content = mp_get_content(taglist->tag, MP_ARTIST); . . artist = mp_parse_artist(content); content = mp_get_content(taglist->tag, MP_TITLE); title = mp_parse_title(content); content = mp_get_content(taglist->tag, MP_YEAR); year = mp_parse_year(content); content = mp_get_content(taglist->tag, MP_GENRE); genre = mp_parse_genre(content); content = mp_get_content(taglist->tag, MP_TRACK); track = mp_parse_track(content); } /*插入子项目数据*/ static void show_item(HWND hList, PLVITEM lvItem) { int i; LVSUBITEM subdata; SendMessage(hList, LVM_ADDITEM, 0, (LPARAM)lvItem); i = lvItem->nItem; subdata.flags = 0; subdata.image = 0; subdata.nItem = i; subdata.subItem = 0; subdata.pszText = artist->text; SendMessage (hList, LVM_SETSUBITEM, 0, (LPARAM) & subdata); subdata.subItem = 1; subdata.pszText = title->text; SendMessage (hList, LVM_SETSUBITEM, 0, (LPARAM) & subdata); subdata.subItem = 2; subdata.pszText = year->text; . . SendMessage (hList, LVM_SETSUBITEM, 0, (LPARAM) & subdata); subdata.subItem = 3; subdata.pszText = genre->text; SendMessage (hList, LVM_SETSUBITEM, 0, (LPARAM) & subdata); subdata.subItem = 4; subdata.pszText = track->text; SendMessage (hList, LVM_SETSUBITEM, 0, (LPARAM) & subdata); } /*创建双向循环链表,将歌曲添加入链表中*/ pnode create_list(char file[]) { LVITEM item; if(head->next == NULL) { strcpy(head->file, file); } else { pnode new; new = (pnode)malloc(sizeof(node)); if(new == NULL){ perror("malloc"); exit(EXIT_FAILURE); } strcpy(new->file, file); tail->next = new; new->prev = tail; tail = new; . . } tail->next = head; head->prev = tail; getid3(file); item.nItemHeight = 25; SendMessage (hListView, MSG_FREEZECTRL, TRUE, 0); item.nItem = count; show_item(hListView, &item); SendMessage (hListView, MSG_FREEZECTRL, FALSE, 0); count = count + 1; } /*播放函数*/ void play(pnode node, HWND hWnd) { node_tmp = node->prev; while(1) { node_tmp = node_tmp->next; if(vfork() == 0){ id_tmp = getpid(); if(execl("./madplay", "madplay", node_tmp->file, NULL)<0) perror("execlp "); }else wait(NULL); } } . . /*主窗口*/ static DLGTEMPLATE playerdlg = { WS_BORDER | WS_CAPTION, WS_EX_NONE, 0, 0, 480, 320, "EDGEplayer", 0, 0, 7,//控件数 NULL, 0 }; /*主窗口控件*/ static CTRLDATA CtrPlayer[] = { { "button", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP, 0, 0, 24, 24, IDC_PLAY, ">", 0 }, { "button", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP, . . 25, 0, 24, 24, IDC_PAUSE, "||", 0 }, { "button", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP, 50, 0, 24, 24, IDC_CONT, "?", 0 }, { "button", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP, 75, 0, 24, 24, IDC_PREV, "<<", 0 }, { "button", WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP, 100, 0, 24, 24, IDC_NEXT, ">>", . . 0 }, { "trackbar", WS_VISIBLE | TBS_NOTIFY | TBS_TIP, 365, 0, 100, 24, IDC_TRACKBAR, "", 0 }, { "listview", WS_VISIBLE | WS_BORDER | WS_CHILD | WS_VSCROLL | WS_HSCROLL, 5, 26, 460,230, IDC_LISTVIEW, "table", 0 }, }; /*关于对话框模板*/ static DLGTEMPLATE aboutcs = { WS_BORDER | WS_CAPTION, WS_EX_NONE, 100, 100, 160, 120, "关于", 0,0, . . 2,//控件数 NULL, 0 }; /*关于对话框控件*/ static CTRLDATA aboutcls[] = { { CTRL_STATIC, WS_VISIBLE | SS_LEFT, 10, 10, 140, 50, IDC_HELP_ABOUT, "EDGEplayer\n史上最烂MP3播放器", 0 }, { CTRL_BUTTON, WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON, 40, 60, 80, 25, IDC_ABOUT_BUT, "返回", 0 }, }; static void Track_notif_callback (HWND hwnd, int id, int nc, DWORD add_data) { int radius=0; . . if (nc == TBN_CHANGE) { /* 当滑块的的位置发生变化时,记录当前值,并通知主窗口重 绘 */ radius = SendMessage (hwnd, TBM_GETPOS, 0, 0); int BASE_VALUE; int mixer_fd; int value; BASE_VALUE=radius; if ((mixer_fd = open("/dev/mixer",O_RDWR))) { printf("Mixer opened successfully,working\n"); value=BASE_VALUE*10; printf("file num %d\n",mixer_fd); if (ioctl(mixer_fd,MIXER_WRITE(SOUND_MIXER_VOLUME),&value)==0) //SOUND_MIXER_VOLUME printf("max successfully.."); else printf("unsuccessfully.."); } else printf("can't open /dev/mixer error.\n"); printf("%d\n",radius); } } //----------------关于对话框处理函数-------------- static int about_proc(HWND hDlg, int message, WPARAM wParam, LPARAM . . lParam) { switch(message){ case MSG_COMMAND: switch (wParam){ case IDC_ABOUT_BUT: EndDialog(hDlg, wParam); break; } case MSG_CLOSE: EndDialog(hDlg,wParam); break; } return DefaultDialogProc(hDlg, message, wParam, lParam); } //----------------创建关于对话框---------------- void about(HWND hWnd) { aboutcs.controls = aboutcls; DialogBoxIndirectParam(&aboutcs, hWnd, about_proc, 0); } /*初始化列表内容*/ static void InitListView(HWND hDlg) { int i; LVCOLUMN lvcol; hListView = GetDlgItem(hDlg, IDC_LISTVIEW); . . for(i = 0; i < 5; i++) { lvcol.nCols = i; lvcol.pszHeadText = capion[i]; lvcol.width = 70; lvcol.pfnCompare = NULL; lvcol.colFlags = 0; SendMessage (hListView, LVM_ADDCOLUMN, 0, (LPARAM) &lvcol); } } /*主窗口过程处理函数*/ static int PlayerWinProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam) { HDC hdc; int i; FILE *stream; pnode tmp; char file[WORD] = "\0"; char dest[WORD] = "\0"; switch (message) { case MSG_INITDIALOG: InitListView(hWnd); SetNotificationCallback (GetDlgItem(hWnd, IDC_TRACKBAR), Track_notif_callback); //滑块绑定回调函数 break; . . case MSG_CLOSE: DestroyMainWindow (hWnd); PostQuitMessage (hWnd); case MSG_COMMAND: switch(wParam) { case IDM_OPENFILE: printf("打开文件\n"); pfdd.is_save = FALSE; strcpy(pfdd.filepath, "./"); strcpy(pfdd.filter, "MP3 File (*.mp3)"); FileOpenSaveDialog(NULL, hWnd, 0, &pfdd); create_list(pfdd.filefullname); break; case IDM_ADDFILE: printf("添加文件\n"); pfdd.is_save = FALSE; strcpy(pfdd.filepath, "./"); strcpy(pfdd.filter, "MP3 File (*.mp3)"); FileOpenSaveDialog(NULL, hWnd, 0, &pfdd); create_list(pfdd.filefullname); break; case IDM_OPENLIST: pfdd.is_save = FALSE; strcpy(pfdd.filepath, "./"); strcpy(pfdd.filter, "LIST File (*.list)"); FileOpenSaveDialog(NULL, hWnd, 0, &pfdd); stream = fopen(pfdd.filefullname, "r"); while(fgets(file, WORD, stream)!=NULL) { . . printf("%s\n", file); /*消除字符串结尾的换行符*/ for(i = 0; i < WORD; i++){ if(file[i] == '\n' || file[i] == '\0') { break; } dest[i] = file[i]; } create_list(dest); memset(file, 0, WORD); memset(dest, 0, WORD); } break; case IDM_SAVELIST: pfdd.is_save = TRUE; strcpy(pfdd.filepath, "./"); strcpy(pfdd.filter, "LIST File (*.list)"); FileOpenSaveDialog(NULL, hWnd, 0, &pfdd); printf("%s\n", pfdd.filefullname); stream = fopen(pfdd.filefullname, "w+"); tmp = head; for(i=0; ifile); tmp = tmp->next; } break; case IDM_ABOUT: about(hWnd); break; . . case IDC_PLAY: printf("1:%d\n", hWnd); if(key_count) { key_count = 0; id_child = fork(); if(id_child == 0){ play(head, hWnd); }else if(id_child > 0){ }else{ perror("fork failed"); exit(1); } } break; case IDC_PAUSE: printf("pause\n"); //kill(id_tmp, SIGSTOP); system("killall -STOP madplay"); //暂停进程 break; case IDC_CONT: printf("continue\n"); //kill(id_tmp, SIGCONT); system("killall -CONT madplay"); break; case IDC_PREV: node_tmp = node_tmp->prev; system("killall madplay"); break; . . case IDC_NEXT: node_tmp = node_tmp->next; system("killall madplay"); break; case IDM_EXIT: if(MessageBox(hWnd, "Do you want to exit?", "exit", MB_YESNO | MB_ICONINFORMATION) == IDYES) { kill(id_child, SIGKILL); kill(id_tmp, SIGKILL); system("killall madplay"); DestroyMainWindow(hWnd); PostQuitMessage(hWnd); return 0; } break; } break; } return DefaultMainWinProc(hWnd, message, wParam, lParam); } /*文件菜单*/ HMENU createfilemenu() { HMENU hmnu; MENUITEMINFO mii; memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; . . mii.id = 0; mii.typedata = (DWORD)"文件"; hmnu = CreatePopupMenu(&mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_OPENFILE; mii.typedata = (DWORD)"打开文件"; InsertMenuItem(hmnu, 1, TRUE, &mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_ADDFILE; mii.typedata = (DWORD)"添加文件"; InsertMenuItem(hmnu, 2, TRUE, &mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_EXIT; mii.typedata = (DWORD)"退出"; InsertMenuItem(hmnu, 3, TRUE, &mii); return hmnu; } /*列表菜单*/ HMENU createlistmenu() { HMENU hmnu; MENUITEMINFO mii; . . memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = 0; mii.typedata = (DWORD)"列表"; hmnu = CreatePopupMenu(&mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_OPENLIST; mii.typedata = (DWORD)"打开列表"; InsertMenuItem(hmnu, 1, TRUE, &mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_SAVELIST; mii.typedata = (DWORD)"保存列表"; InsertMenuItem(hmnu, 2, TRUE, &mii); return hmnu; } /*帮助菜单*/ HMENU createhelpmenu() { HMENU hmnu; MENUITEMINFO mii; memset(&mii, 0, sizeof(MENUITEMINFO)); . . mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = 0; mii.typedata = (DWORD)"帮助"; hmnu = CreatePopupMenu(&mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_ABOUT; mii.typedata = (DWORD)"关于"; InsertMenuItem(hmnu, 1, TRUE, &mii); return hmnu; } HMENU createmenu() { HMENU hmnu; MENUITEMINFO mii; hmnu = CreateMenu(); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_FILE; mii.typedata = (DWORD)"文件"; mii.hsubmenu = createfilemenu(); InsertMenuItem(hmnu, 0, TRUE, &mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; . . mii.state = MFS_ENABLED; mii.id = IDM_LIST; mii.typedata = (DWORD)"列表"; mii.hsubmenu = createlistmenu(); InsertMenuItem(hmnu, 1, TRUE, &mii); memset(&mii, 0, sizeof(MENUITEMINFO)); mii.type = MFT_STRING; mii.state = MFS_ENABLED; mii.id = IDM_HELP; mii.typedata = (DWORD)"帮助"; mii.hsubmenu = createhelpmenu(); InsertMenuItem(hmnu, 2, TRUE, &mii); return hmnu; } int MiniGUIMain (int argc, const char* argv[]) { HMENU hMnu; pfdd.is_save = FALSE; strcpy(pfdd.filepath, "./"); strcpy(pfdd.filter, "MP3 File (*.mp3)"); key_count = 1; count = 0; head = (pnode)malloc(sizeof(node)); if(head == NULL){ perror("malloc"); exit(EXIT_FAILURE); . . } head->next = NULL; head->prev = NULL; tail = head; hMnu = createmenu(); playerdlg.hMenu = hMnu; playerdlg.controls = CtrPlayer; DialogBoxIndirectParam(&playerdlg, HWND_DESKTOP, PlayerWinProc, 0); return 0; } .
/
本文档为【mp3播放器设计论文】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
热门搜索

历史搜索

    清空历史搜索