音视频数据采集的设计 - 图文

更新时间:2024-03-28 14:59:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

创作设计说明书

嵌入式音视频数据采集模块的设计

学 院:

专 业:

学生姓名:

学 号:

指导教师:

年 月

目录

目 录

目 录 ............................................................................................................................. I 摘 要 ........................................................................................................................... 1 ABSTRACT .................................................................................................................. 2 第一章 序言 ................................................................................................................. 3

1.1 课题目的 ......................................................................................................... 3 1.2 资料调研分析 ................................................................................................. 3 1.3 设计简介 ......................................................................................................... 3 第二章 设计要求及方案的确定 ................................................................................. 5 2.1 设计要求 ......................................................................................................... 5 2.2 方案的确定 ..................................................................................................... 5 2.2.1 方案的实现 ............................................................................................... 5 2.2.2 设计流程 ................................................................................................... 6 第三章开发环境的搭建及硬件系统 ........................................................................... 9 3.1 软件开发环境的搭建 ..................................................................................... 9 3.2 硬件系统 ....................................................................................................... 10 3.2.1凌阳 cortex A8开发板简介 ................................................................... 10 3.2.2音频输出接口和麦克风 .......................................................................... 12 3.2.3 电容屏输出接口 ..................................................................................... 13 3.2.4 USB2.0 HOST 接口 ................................................................................ 15 3.2.5摄像头外设 .............................................................................................. 16 3.2.6串口及串口电路 ...................................................................................... 17 第四章 音视频程序的设计与功能实现 ................................................................... 19 4.1 主界面的设计及功能实现 ........................................................................... 19 4.1.1 主界面的设计 ......................................................................................... 19 4.1.2 功能实现 ................................................................................................. 19 4.2 录放音界面的设计及功能实现 ................................................................... 21 4.2.1 录音界面的设计 ..................................................................................... 21 4.2.2 录音界面功能的实现 ............................................................................. 22 4.2.3 放音界面的设计 ..................................................................................... 22 4.2.4 放音界面功能的实现 ............................................................................. 22 4.3 录像、拍照界面的设计及功能实现 ........................................................... 24 4.3.1 录像、拍照界面的设计 ......................................................................... 24 4.3.2 录像功能的实现 ..................................................................................... 24 4.3.3 拍照功能的实现 ..................................................................................... 25

I

4.4 播放视频、图片界面设计及功能实现 ....................................................... 27 4.4.1 播放视频界面设计 ................................................................................. 27 4.4.2 播放视频界面功能的实现 ..................................................................... 27 4.4.3 图片浏览界面的设计 ............................................................................. 28 4.4.4 图片浏览界面功能的实现 ..................................................................... 28 第五章 功能测试与BUG分析 ................................................................................. 30 5.1 功能测 ........................................................................................................... 30 5.2 BUG分析与解决 ........................................................................................... 30 结论 ............................................................................................................................. 33 致谢 ............................................................................................................................. 34 参考文献 ..................................................................................................................... 35 附录 ............................................................................................................................. 36

摘要

摘 要

嵌入式音视频数据采集的设计,是以Linux系统为开发环境,cortoex A8开发板作为硬件开发平台,结合linux C语言开发而成的。使用麦克风、摄像头、扬声器和电容屏等硬件设备,通过linux c程序编程对开发板的麦克风进行录音,采集音频数据,存储录音文件,并使用扬声器播放录制的音频,完成对音频数据的采集功能。把摄像头插到开发板上,通过程序读写音视频设备使摄像头采集实时采集图像数据,存储为图片和视频,显示在电容屏上,并实现拍照,照片浏览、录像、播放录像等视频数据采集功能。

关键字 :linux C 、cortex A8 开发板、麦克风、摄像头、扬声器、电容屏

1

摘要

Abstract

The design of the embedded audio and video data collection is based on Linux system as the development environment , cortoex A8 development board as hardware development platform, combined with Linux C language development, The design uses the microphone, camera, speakers and capacitance screen devices of hardware to collect data .The first, using Linux c programs for the microphone of development board to collect the data of audio .the second the design will save the recording file, and use the speaker to play the recorded audio.Then it can complete the function of audio data acquisition.Pluging the camera into development board, it makes the camera to collect real-time acquisition with the program to read and write av equipment.the date of Image will be stored as images and video. It shows in the capacitance screen. It can realize function of the photo and photo browsing, video recording, video playing and video data acquisition .

Keywords: linux C, cortexA8 development board, microphone, camera, speaker,capacitive screen

第一章

第一章 序言

1.1 课题目的

随着多媒体技术的飞速发展,人们对于生活质量的要求以及安全意识也在日益增长,音视频等多媒体技术在嵌入式开发中的广泛应用既是最直观的体现,日常生活中,人们使用各种嵌入式产品摄像、拍照的现象随处可见,大街小巷也都有安防摄像头。而这些现象的核心就是音视频信息采集,它是视频处理再加工以及安防监控的基础,而嵌入式音视频数据采集模块的设计,对音频,视频数据进行采集、存储、应用,恰恰能够为视频处理和安防监控提供基础,以及为学生学习音视频处理提高技术支持,既是我这次毕业设计的目的。

1.2 资料调研分析

近年来随着嵌入式行业的迅速发展,嵌入式产品日益成为人们生活的必需品,

并且随着技术的进步,嵌入式产品正朝着高端低成本的方向发展,其中基于嵌入式的音视频技术就是最好的案例,音视频等多媒体技术在嵌入式开发中应用极为广泛,例如:摄像头图像采集、LCD显示图片、音频采集与播放等在嵌入式各产品中都会有所涉及。国内外又没有专门音视频信息采集的基础软件,而嵌入式音视频数据采集模块的设计作为音视频数据采集的基础软件,以Linux系统为开发环境,arm A8架构作为硬件平台大大节约了开发成本,提高项目的可移植性,不仅可以做为人们生活的娱乐产品,还可以为视频处理再加工以及安防监控提供基础,符合嵌入式发展的需求。

1.3 设计简介

本设计是嵌入式音视频数据采集的,实现录放音、录像、播放录像,拍照、图片浏览等功能,主要分为音频数据和视频数据的采集、应用两个部分。使用凌阳公司提供的 cortex A8开发板,通过linux c程序编程对开发板的话筒进行录音,并用扬声器播放录制的音频,把摄像头插到开发板上,通过程序读写

3

第一章

音视频设备使摄像头采集的图像并显示在液晶屏上,并实现拍照,照片浏览等功能。

音频部分主要是通过采集电路(麦克风)得到的是一种连续变化的音频信号(模拟信号),在经过AD转换电路将音频信号转换为计算机可以处理的数字信号,进行存储,实现音频数据的采集。录音时,先设置好采样频率、采样位数、声道数,再启动声卡的AD芯片,将音频的模拟信号转化为数字信号,最后将音频对应的数字信号存储到文件中。放音时需要依据录音时声卡的采样频率、采样位数、声道数去设置声卡,再将音频的数字信号通过声卡的DA芯片转化为音频对应的模拟信号。

视频部分主要是通过C编程从摄像头连续捕捉一帧图像并按照一定的时间间隔显示电容屏上,显示图像时,若图像每秒变化超过24次,根据余晖效应,此时人眼无法辨别单幅的静态图像,一张一张静态的图像看上去是连续的运动的,从而形成了视频。从摄像头获取的图像是原始yuv格式的数据,需要同编程将捕获的每一帧图像转换为一定格式的图片按照一定规则进行存储,从而实现视频数据的采集。

第二章

第二章 设计要求及方案的确定

2.1 设计要求

(1)能够录音并存储为wav格式的音频文件。 (2)播放已经存在的wav格式的音频文件。

(3)视频采集与显示,能够实时从摄像头中获取图像并将摄像头获的帧数

据显示到屏幕上。

(4)拍照,捕捉一帧图像保存为bmp照片。

(5)照片浏览,能够把存储的bmp图片显示在电容屏上。 (6)录像,存储摄像头获得的数据,保存为mpg格式视频。 (7)播放录像,能够将存储mpg格式的视频播放出来。 (8) 图片及音频或视频支持自动播放 (9) 音频文件、视频文件选择目录显示并播放

2.2 方案的确定

2.2.1 方案的实现

音视频数据采集基础主要有两部分组成:硬件部分和软件部分

(1)硬件部分主要采用凌阳提供的coterx A8 开发板,以及外设摄像头 (2)软件部分主要分为两个方面:界面设计和功能实现

界面部分:界面设计主要由gtk+ 与glade 完成,首先由glade设计界生产xml文件,利用gtk+ 提供的函数接口读取xml文件就能生产相应的界面。功能

5

第二章

实现:功能实现主要是以Linux C 编程为主,通过进程,线程,管道,以及信号量的使用来实现音视频数据采集

音频部分:Linux系统为用户操作音频设备提供了统一的编程接口,oss音频框就是其中一种,由于其比较简单容易操作,并且稳定性比较好在音频编程中被广泛使用。Linux下一切设备皆文件,因此通过oss音频提供的接口驱动音频设备文件/dev/dsp ,/dev/dsp:录音、放音对应的设备文件。向/dev/dsp文件中写数据会激活声卡上的D/A转换器进行放音。从/dev/dsp文件中读数据则会激活声卡上的A/D转换器进行录音。

视频部分:在Linux中,视频的采集、输入及输出主要采用V4L2框架,在V4L2编程框架中,内核为应用程序提供了访问音、视频设备的统一接口。通过V4L2接口操作视频设备可以像访问普通文件一样对设备文件进行读写。dev/videoX(X为数字0、1、2、...)对应着摄像头的设备文件。对设备文件进行读写完成视频数据的采集与播放。

视频显示:通过gtk+开源库显示采集到的图像。并且可以自由指定图像的大小,先将摄像头输出的yuv原始数据转换为rgb数据,再通过函数gtk_draw_rgb_image()接口将数据绘制到绘图区,显示在电容屏之前可以指定绘图区的大小,从而改变显示图像的大小。

2.2.2 设计流程

第二章

(1)界面切换流程图

图2-1 各功能界面之间切换流程图

(2)录音、播放录音流程图

图2-2 录音播放录音功能实现流程图

第二章

(3)录像、拍照流程图

拍照、录像窗口初始化V4L2音频框架打开录像/dev/videoX设备选择拍照or录像播放录像or浏览图片创建线程,实时从摄像头中获取图像创建线程,实时触发曝光事件显示图像拍照录像、开线程浏览图片播放录像、开线程获取一帧图像转换为bmp格式,保存图片将每帧图像转换为jpge格式,按一定的格式存储为mpg格式文件读取图片,转换rgb格式,显示在屏幕上从文件中读取帧数据,转换为rgb格式,按一定的频率显示在屏幕上关闭文件,回收线程资源关闭文件,回收线程资源 图2-3 录像、拍照功能实现流程图

第三章

第三章开发环境的搭建及硬件系统

3.1 软件开发环境的搭建

嵌入式音视频数据采集模块的设计是在linux下编程,安装物理机比较繁琐,对硬件要求也比较高,所以我选择安装虚拟机,在虚拟机上安装linux系统,我选择安装的虚拟机是 vmware workstation 10 ,linux版本是Ubuntu 12.04.2。 然而linux下没有好的代码编辑、工程管理工具,windows下的Source Insight 项目管理编写软件,恰恰能满足这方面的要求,但需要在linux下编译,所以就用到了window与linux交互工具samba与xshell。

嵌入式音视频数据采集的界面设计主要由gtk+ 与glade 完成,首先由glade设计界面生产xml文件,利用gtk+ 提供的函数接口读取xml文件就能生产相应的界面。

GTK+是一套在GIMP的基础上发展而来的高级的、可伸缩的现代化、跨平台图形工具包,它可以很方便地制作图形交互界面( GUI )。特点:稳定、跨平台、多种语言绑定、接口丰富、与时俱进、算法丰富、移动嵌入式应用广泛。 Glade是GTK+中跨平台的图形用户界面设计工具,Glade工具允许用户快速和高效地设计图形用户界面。用Glade设计的图形用户界面是以XML格式的文件保存,它描述了控件的结构、每个控件的属性。用户可以动态加载这个界面文件。界面和程序逻辑是完全分离,用户修改了界面,也不需要重新编译程序 最后开发程序要在cortex A8开发板运行,需要为cortex A8开发板制作linux内核以及linux文件系统,这里就不做过多的介绍,要想电脑上开发的程序能在cortex A8开发板上使用,还需要在电脑上搭建arm-linux-gcc跨平台编译环境。

至此嵌入式音视频数据采集设计的软件开发环境搭建好了。

9

第三章

3.2 硬件系统

3.2.1凌阳 cortex A8开发板简介

凌阳 cortex A8开发板是凌阳教育开发的嵌入式标准的开发平台。处理器采用了业界领先的cortex A8 ,其内部拥有丰富的模块,另外该芯片主频高达833M HZ,可以轻松上手学习嵌入式操作系统的设计及开发。凌阳 cortex A8开发板基于开发考虑,外设比较齐全,接口标准,扩展功能方便。整个开发板采用核心板加底板方法设计,核心板采用了八层板的设计,线路可靠稳定,是嵌入式学习和研究的最佳选择,该实验仪适合研究人员和电子爱好者用做性能评估与开发。

1 、核心板主要元件: (1)CPU 型号为 S5PV210

(2)DDR2 内存,一共 4 片,型号为 K4T1G164Q

(3)NAND FLASH,1G 版本核心板为 K9K8G08,256M 版本核心板为 K9F2G08 (4)有线网络芯片,10/100Mbps,SMSC LAN9220

(5)AC97 音频编解码芯片,WM9713,该芯片包含电阻式触摸屏控制器 (6)电源转换芯片,为核心板器件提供所需要的各种电压转换。 2 、底板主要元器件:

(2)电源接口,输入电压为 5V。电源上串联有一个 1.1A 的自恢复保险丝。 (2)电源开关,选用进口优质电源开关,可反复开关不低于 10 万次。 (3)USB2.0 OTG 接口,采用 mini USB 插座,支持 480Mbps 高速模式。 (4)HDMI 高清显示输出,标准的 Type A 型 HDMI 插座,机械强度高。 (5)CVBS 视频输出端口,用于连接电视机。 (6)100M 有线以太网接口。

(7)2 路 RS232 电平串口插座,DB9 针式插座,和 PC 串口标准一致。 (8)TF 卡插座,支持从 TF 卡启动。

(9)板载 USB WIFI 模块(板载和外接二选一),支持 802.11n 150Mbps。 (10)3 路预留 USB 2.0 HOST 端口,可以外接 U 盘,鼠标,键盘等。

第三章

(11)音频输出接口,采用 3.5mm 耳机插座。板载麦克风。 (12)启动模式设置开关,可以设置多种启动模式。 (13)4 个用户 LED,由用户程序控制 LED 的亮灭。 (14)摄像头输入接口,可以连接定制的摄像头扩展板。 (15)液晶输出接口,可以外接各种液晶屏模块。 (16)RTC 时钟电池。

(17)GPIO 扩展接口,包含 2 路串口,1 路 SPI,一个 GPIO。 (18)9 个用户按键,支持常用的功能操作。1 个复位按键。 3、实物图

图3-1 凌阳教育cortex A8 开发板

第三章

开关电源电源插座USB OTGHDMI视频端口以太网UART1UART3核心板复位键TF卡插座UARTSPIGPIO接口板载USBWIFI焊接位置USB HOST1用户功能按键USB HOST2USB HUB芯片USB HOST3耳机插座RTC时钟电池液晶屏背光驱动电路液晶屏接口插座摄像头接口插座用户LED耳机插座启动模式设置开关麦克

图3-2 Cortex A8 开发板核心板加底板

3.2.2音频输出接口和麦克风

音频输出端口(J11)为标准 3.5mm 立体声耳机插座,接到 AC97 编解码芯片WM9713 的音频输出。麦克风(MIC1)也是接到 WM9713。

当耳机插入耳机插座时候,耳机插头的金属部分会把耳机插座的第 3 脚和第 4 脚短接。第 3 脚是地线,这样相当于把第 4 脚接地,而第 4 脚和喇叭的功放使能引脚相连接,第 4 脚接地时候为低电平,喇叭功放就停止工作。也就是说,耳机插入插座会自动禁止喇叭的声音。

第三章

图3-3 编解码芯WM9713电路图

图3-4 扬声器电路图

3.2.3 电容屏输出接口

液晶屏输出接口(J9)用于连接各种液晶屏,包含了液晶屏数据信号,背光电源和触摸屏这 3 个部分。

第三章

图3-5 液晶屏输出接口

液晶屏接口插座使用的是 0.5mm 间距 40 芯 FPC 插座,下接触。插入 FPC 带线时候,要把 FPC 带线的金属接触面朝下。FPC 插座左边为第 1 脚(白色三角形)。

LCD 的 35 脚 LCDSEL 是一个识别 5 寸和 7 寸液晶屏的引脚,电路板上有一个下拉电阻。对于 5 寸的液晶屏模块,这个引脚是空脚,所以是低电平。对于 7寸液晶屏,35 脚是接高电平。因为 5 寸液晶屏和 7 寸液晶屏分辨率是一样的,只是背光电流要求不同,所以 LCDSEL 用于控制背光电流的大小[12]。 LCDSEL 为低电平情况,Q9 不导通,背光电流 I=0.1/R=0.1/3.3=0.03A=30mA。 LCDSEL 为高电平情况,Q9 导通,R27 和 R26 并联,R=R27*R26/(R27+R26)=1R, 背光电流 I=0.1/R=0.1/1=0.1A=100mA。

第三章

图3-6 液晶屏电路图

3.2.4 USB2.0 HOST 接口

S5PV210 只有 1 路 USB2.0 HOST 端口,底板上通过 USB HUB 芯片 GL850G 扩展出 4 个 USB2.0 端口,其中一个用于板载 WIFI 接口,剩余 3 个是标准的 USB A型接口插座,分别是 J23,J24,J25。支持高速模式,也就是 480Mbps。之前三星的 S3C2440A 和 S3C6410 的 USB HOST 最高只支持 USB 2.0 全速(12Mbps)模式。

S5PV210 只有 1 路 USB2.0 HOST 端口,底板上通过 USB HUB 芯片 GL850G 扩展出 4 个 USB2.0 端口,其中一个用于板载 WIFI 接口,剩余 3 个是标准的 USB A型接口插座,分别是 J23,J24,J25。支持高速模式,也就是 480Mbps。之前三星的 S3C2440A 和 S3C6410 的 USB HOST 最高只支持 USB 2.0 全速(12Mbps)模式。

第三章

图3-7 USB电路图

图3-8 USB实物图

1:VCC (5V),为接入 USB 端口的设备提供电源 2:USB D-,也用 DM 表示,USB 差分信号- 3:USB D+,也用 DP 表示,USB 差分信号+ 4:GND 电源地

3.2.5摄像头外设

高品质CMOS感应器。支持Windows XP SP2 / Vista等操作系统。支持手动式调焦。静态图像拍照:默认分辨率为640x480。视频录像捕捉:默认分辨率为640x480,软件增值可达到500万(2560x1920),YUY2输出格式。

USB2.0高速传输,高帧速(30-15fps)视频播放,画面流畅不停顿。自动白平衡、曝光。最小灵敏度:2.0V/Lux.Sec。闪烁控制:50Hz或60Hz自动识别。支持抓取、储存静态照片(JPG格式)功能。支持QQ、MSN、雅虎通等视频聊天

第三章

软件,等视频聊天室。工作温度:-10~60℃。功耗:<0.5W。

图3-9 摄像头实物图

3.2.6串口及串口电路

S5PV210 一共有四个串口,其中 2 个通过 SP3232 电平转换芯片连接到 DB9插座。另外 2 个直接从 CPU 连接到开发板 J17 插座。

图3-10 串口电路图

第三章

图3-11 串口管脚定义

开发板的 DB9 串口信号定义和 PC 的串口定义完全一样: 2:RXD 接收信号,对于开发板来说是输入信号 3:TXD 发送信号,对于开发板来说是输出信号 5:GND 公共地

第四章

第四章 音视频程序的设计与功能实现

4.1 主界面的设计及功能实现

4.1.1 主界面的设计

主界面的设计模板主要在windows下Glade-3.6.6界面设计软件下设生成xml文件,通过linux下开源gtk+库中函数接口获取解析模板 ,并通过函数接口获得模板中的控件,使用插入图片接口为窗口插入背景,为控件插入图片。 函数接口:

window->gxml= glade_xml_new(MAIN_WINDOW, NULL, NULL);//解析设计模板window->main_win.main_window=glade_xml_get_widget(window->gxml,\_window\获取glade定义的控件

sungtk_background_set_picture(window->main_win.main_window,\/back.jpg\为窗口设置背景

sungtk_button_inset_image(window->main_win.wav_button,\png\为控件插入图片

主界面内容:音频采集按钮,视频采集按钮,退出程序按钮,时间标签

4.1.2 功能实现

主界面的主要功能是功能选择,选择录像还是录音,点击录像,录音按钮会进入相应的功能窗口,点击退出按钮会推出程序。

当点击功能按钮时,会触发点击\事件,通过接口调用相应按钮触发的回调函数,点击录音,录像按钮时,会调用gtk_widget_hide_all()接口隐藏主界面,gtk_widget_show_all()接口更换已经初始化好的相应的功能界面,点击关闭按钮,调用gtk_main_quit()退出窗口,并退出程序

19

第四章

设计模板及效果图:

图4-1 主界面模板

图4-2 主界面窗口视图

第四章

4.2 录放音界面的设计及功能实现

4.2.1 录音界面的设计

录音界面主要包括录音按钮,放音界面按钮,返回按钮。 设计模板及效果图如下:

图4-3 录音界面设计模板

图4-4 录音界面效果图

第四章

4.2.2 录音界面功能的实现

录音界面功能主要包括,录音功能,进入放音界面功能,返回主界面功能。 录音功能:当接入录音界面时先初始化/dev/dsp录音设备,设置采样位数,采样通道,采样频率(正常人耳识别频率:20~20khz),这次设计我采用的采样频率是22050hz(22khz),通道数为2,采样位数为16,一秒采集到的数据大小为88200Byte,点击录音按钮,开启一个线程,按照时间新建并打开一个.wav 文件,开始录音,对于.WAV格式的音频文件先设定44字节的头并写入文件头部,然后通过read()接口不断的从/dev/dsp音频设备读取音频数据,并循环不停的将采样数据通过write()接口写入文件,直到点击停止录音按钮,将音频数据的大小写入wav文件头部,存取文件到指定路径,完成录音,连续录音,需要结束并回收上次录音的线程资源。

进入放音界面:隐藏录音界面,显示播放录音界面窗口即可。

返回主界面:隐藏录音界面,显示主界面窗口即可,返回主界面会同时关闭录音设备。

4.2.3 放音界面的设计

放音界面主要包括,播放录音按钮,删除录音文件按钮,返回按钮, 录音文件列表等控件。

4.2.4 放音界面功能的实现

放音界面功能主要包括,显示录音文件功能,删除录音文件功能,自动播放功能,返回录音界面功能。

显示及播放录音文件功能的实现:进入播放录音界面先通过opendir 和readdir读取指定路径的.wav文件并显示在屏幕上,点击屏幕上的.wav文件时,分栏列表会产生一个信号,触发选择文件\事件,调用事件回调函数,在回调函数中会开启一个线程,在这个线程中先读取wav文件的44个字节的头部,从中解析出录用数据的长度,根据数据长度,不停的读取.wav文件中

第四章

录音数据,每次读到的数据大小为88200Byte,同录音时每次从音频设备读取的大小相同,并写入音频设备实现放音,直到每次读取的音频数据的累积等于文件音频数据长度,或切换录音为止,连续切换播放录音,需要结束并回收上次录音的线程资源。

删除录音文件:点击选中的录音文件,通过接口remove( wav格式文件路径)删除即可。

自动播放功能:点击播放按钮即可实现自动播放录音,播放录音实现如上所述,当一个录音文件播放完后,会自动进入循环播放录音模式,点击该按钮可停止。

返回录音界面:隐藏当前窗口,显示录音窗口。

录音、播放录音功能实现可参考 图2 录音播放录音功能实现流程图。 设计模板及效果图:

图4-5 放音界面设计模板

第四章

图4-6 放音界面效果图

4.3 录像、拍照界面的设计及功能实现

4.3.1 录像、拍照界面的设计

录像、拍照界面包括拍照、录像选择标签,拍照、录像按钮,录像播放窗口按钮,图像刷新显示区域,返回按钮。

4.3.2 录像功能的实现

当进行拍照、录像界面时,首先初始化V4L2 视频框架,通过接口video_init_device(&window->video,\

\视频设备,通过接口video_start_capturing(&window->video)开启图像捕捉功能,开启线程通过V4L2接口video_get_frame(&window->video, video_frame_rgb, rgb)实时获取摄像头中图像数据并将yuv数据转换rgb格式数据,,GTK中的绘图函数只能够显示rgb格式的数据。需要将摄像头yuv数据转化成rgb数据。

获取摄像头数据在开发板屏幕显示,通过GTK在屏幕实时显示需要刷新绘图区域,实时使用gtk_widget_queue_draw()接口就会自动调用曝光事件所连接

第四章

的回调函数,回调函数中通过调用gdk_draw_rgb_image()接口刷新屏幕从而实现实时显示;

录像时,点击选中录像标签,点击录像按钮,就会开启录像线程,实时获取图像并写入视频文件,直到点击该按钮停止为止。由于rgb数据是原始数据未压缩,直接存储采集的数据会导致视频文件很大,浪费内存空间,所以需要将rgb数据压缩,即将rgb格式的数据转化为jpg格式的数据进行存储,rgb转jpg的函数为:

int compress_rgb24_to_jpeg_buffer(unsigned char *rgb24,

unsigned int width, unsigned int height, unsigned char *jpeg_buffer, int buffer_size, int quality);

视频文件内容 = jpg的大小+jpg内容[+jpg的大小+jpg内容]...

4.3.3 拍照功能的实现

拍照功能,首先点击选中拍照标签,点击录像、拍照按钮,通过调用接口摄像头就会实时捕捉一张图像,但摄像头捕获的图像是由yuv转换的rgb,要通过图片格式转换函数:void rgb24_to_bmp(unsigned char *rgb24, char *bmp_name, int width, int height)将rgb图像转换为bmp格式图片,并按照当前时间取名保存bmp格式文件。

拍照、录像功能实现可参考 图3 录像、拍照功能实现流程图 点击返回主窗口按钮时,会反初始化视频设备,关闭图像捕捉设备。

第四章

设计模板和效果图如下:

图4-7 录像拍照界面设计模板

图4-8 录像拍照界面效果图

第四章

4.4 播放视频、图片界面设计及功能实现

4.4.1 播放视频界面设计

播放视频界面主要包含:图像显示区域,视频文件列表,删除视频文件按钮,

返回按钮。

4.4.2 播放视频界面功能的实现

播放视频界面功能:显示mpg格式文件列表,删除视频文件,返回录像、拍照窗口。

视频文件显示及播放功能实现:进入播放录音界面先通opendir 和readdir

读取指定路径的.mpg文件并显示在屏幕上,点击屏幕上的.wav文件时,分栏列表会产生一个信号,触发选择文\事件,调用事件回调函数,打开选择的视频文件,不停读取视频文件中的图像,先读取jpg大小,再读取jpg数据,将读取的图像显示在电容屏的窗口上,由于读出的图像的格式为jpg格式,所以要将图像数据通过接口再转化为rgb数据格式,转化函数为:int decompress_jpeg_buffer_to_rgb(unsigned char *jpeg_buffer,

int jpeg_size, unsigned char **rgb, int *width, int *height))。

直到读取不到视频数据,视频播放完或者切换视频为止,连续切换播放视频,需要结束并回收上次播放的线程资源。

录像文件的删除同音频文件删除功能实现方式相同。

第四章

设计模板和效果图如下:

图4-9 录像播放界面设计模板

图4-10 录像播放界面效果图

4.4.3 图片浏览界面的设计

图片浏览界面主要包括:上一张,下一张,自动播放按钮,返回按钮等。

4.4.4 图片浏览界面功能的实现

图片浏览界面功能主要有,点击上一张,下一张,可以切换图片,点击自动

播放按钮,可以自动播放播放图片。

第四章

图片的播放:进入图片浏览界面,通opendir 和readdir读取指定路径的.mpg

文件,存放在链表中,当点击播放图片是,读取.bmp文件,通过接口sungtk_image_load_picture(),将图片显示在电容屏上。

返回功能:隐藏图片浏览窗口,显示拍照录像窗口。 设计模板与效果图:

图4-11 图片浏览界面设计模板

图4-12 图片浏览界面效果图

第五章

第五章 功能测试与BUG分析

5.1 功能测

功能测试表5-1

功能 各界面之间切换顺畅,没有卡顿现象 录音,保存为wav格式 顺畅播放保存的录音文件 录音播放时切换录音文件 删除录音文件 拍照保存为bmp格式图片 图片浏览,自动、手动浏览图片 录像,保存mpg格式视频 顺畅播放录像 播放录像时切换录像文件 录像删除 音频文件、视频文件选择目录显示并播放

是否实现 实现 实现 实现 实现 实现 实现 实现 实现 实现 实现 实现 实现 5.2 BUG分析与解决

BUG分析与解决表5-2

bug 界面 创建界面时图片显示不全 切换窗口 出现段错误 没有释放窗口,易卡死 图片路径是否正确,复制粘贴按钮时,是否更改了需要改的信息 1、要及时处理隐藏窗口的数据,如果窗口要销毁,要在销毁前要及时处理 2、指针、变量的初始化 释放主窗口,子窗口被释放 30

解决方法 第五章

回调函数,不起作用 按钮图片不能正常显示图片大小 各界面切换速度很慢 回调函数断开了,从按钮开始,一步一步往下找错误。 获得图片资源没有设置大小,使用的默认大小 程序在开始时就对各界面进行初始化,离开界面不必关掉,只在程序退出时关掉各界面,避免了每次切换界面,界面初始化对时间的浪费 录音、放音 每次进入相应的窗口中打开一次设备,退出窗口再关闭设备 1、先检查文件和设备是否正常打开,参数是否配置正确 播放声音时,不能正常播放 2、在检查读写是否正确 3、还要检查声音文件是否为空 在给出的picture_window.c里有更换控件的录音时,不会更换图片按钮 函数,要注意使用 录音返回窗口,如果在放音,切换窗1、在切换窗口时,设置标志位解决 口,依然放音 2、停止录音播放线程 参数是否配置正确(应该仔细配置,不能有一不能正常录音 点错误),应该开 线程不停从设备里读取,存在文件里 可以有3个参数不能写成因open函数的参数不正确导致不能open(pd,O_RDWR|O_CREATE|0777); 正常读写 权限是第三个参数 滚动条里的声音文件或者视频文件,在进入界面时,先清空列表,再扫描歌曲。 会重复的增加 频繁打开、关闭设备容易卡死 录视频、放视频 应该先获得一帧图像,在建线程不断刷新屏幕gdk_threads_enter(); gtk_widget_queue_draw(draw); // 更新刷图区域 gdk_threads_leave(),建曝光窗口时应该放在table里 video窗口的曝光窗口不能曝光 没有写进文件,检查打开文件参数是否正确,录制的视频大小为0 权限是否正确, 写的时候是否正确 播放视频,定义数组去保存转化的数定义指针要malloc空间 第五章

据时,视频无法播放 播放视频,结尾时异常 录制视频时,是否正确,是否正常结束了 播放视频,停止时break,屏幕卡死,break的地方不对,信号量都变成了0,刷新的没有段错误 函数堵塞???怎么工作解决 While刷新draw时,视频播放不了,当刷新整播放视频界面打开后关闭,再打开视个窗口时, 频无法播放 再打开视频就可以播放 在正在播放视频时,返回上层界面,再返回上层窗口时,切换到暂停标志位,并取会卡屏 消线程 1、检查录制的视频是否正确 播放视频不成功 2、还要检查路径是否正确 3、视频文件是否正常 使用信号量,让刷新,曝光,录视频按次序进录制视频时,只能录制几秒钟 行。同步处理 在从文件里读取数据时,判断读取的长度,是播放完视频,段错误,或者killed否为0, 退出程序 为0,则break,退出循环。 在曝光函数绘图时,判断rgb是否为空,如果播放视频时,一开始,曝光界面就卡为空, 屏 不让绘图; 视频在播放状态时,点击列表播放视频, 在播放下一个视频时,关闭先前的文件描述符 视频不断地播放上一个视频和选中的视频 一进入播放视频界面就卡死 信号量顺序不对,把信号量的顺序调整 录像时退出窗口,卡屏 退出时,暂停录像,关闭线程,设置标志位

结论

结论

嵌入式音视频数据采集的设计,通过linux C编程实现了从硬件麦克风和摄

像头采集音视频数据,保存为特定格式的文件,并能够通过扬声器将录音文件播放,电容屏播放录像文件。通过点击电容屏上相应功能的按钮,完成相应的功能,实现嵌入式音视频数据采集的设计功能。

这次设计的突出之处是对切换播放录音、播放录像的处理,切换播放录音、

录像不会发生与切换之前的录音、录像混播的现象,并且播放录音、录像时点击返回、删除录像,不会出现任何的卡顿现象。

由于知识和时间的有限,这次对录像,播放录像的处理没有涉及到编解码的

相关应用,所以在播放录像的格式目前只支持通过本设备的录制的录像文件,录音的播放目前也只支持播放wav格式的文件。

这次设计只是简单实现了音视频数据的采集功能,在后续的完善中会对录像

加入视频编解码相关的应用,并支持多种格式视频音频文件的播放。同时会加入显示制定文件夹音乐文件,播放音乐等相应的功能。

33

致谢

致谢

34

参考文件

参考文献

[1] 刘刚, linux系统移植.北京.清华大学出版社

[2] 孙琼, 嵌入式LinuxC语言应用程序设计(修订版) .北京.人民邮电出版社 2014 [3] 杨斌, 嵌入式系统应用开发基础 西安 电子工业出版社 2011.08

[4] 陈赜, ARM嵌入式技术原理与应用 北京 北京航空航天大学出版社 2011-01-01 [5] 弓雷, ARM嵌入式Linux系统开发详解 北京 清华大学出版社 2014-02-01 [6] 黎胜容, ARM嵌入式项目开发三位一体实战精讲 北京 北京航空航天大学 出版社 2011-10-01

[7] 哈利南, 嵌入式Linux基础教程(第2版) 北京 人民邮电出版社 2012-05-01 [8] 李朱峰, Linux2.6嵌入式系统开发与实践 北京 北京航空航天大学出版社 2010-05-01

[9] 文全刚, 嵌入式Linux操作系统原理与应用 北京 北京航空航天大学出版社 2011-03-01

[10] 韦东山, 嵌入式Linux应用开发完全手册 北京 人民邮电出版社 2008-08-01 [11] 怯肇乾, 嵌入式图形系统设计 北京 北京航空航天大学出版社 2009-03-01 [12] 郑灵翔, 嵌入式接口技术与Linux驱动开发 北京 北京航空航天大学出版社

2010-04-01

[13] 闫广明, 嵌入式Linux 北京 清华大学出版社 2012-02-01 [14] 杨胜利//刘洪涛, ARM嵌入式体系结构与接口技术 北京 人民邮电出版社

2013-09-01

[15] APress , Andrew Krause Foundations of GTK+ Development 2007 4 1 [16] 蔡建平, 软件综合开发案例教程 北京 清华大学出版社 2011/02 [17] Karim Yaghmour,JonMasters,Gilad Ben-Yossef,Philippe Gerum Building

Embedded Linux Systems O'Reilly Media, Inc, USA;2nd Revised edition 2008年8月1日

[18] Brian W.Kernighan,Dennis M.Ritchie The C Programming Language

Prentice Hall PTR 2004-1

[19] 邓有训.空军雷达学院学报[J].武汉:空军雷达学院出版社,2000:52.

35

附录

附录

设计主程序初始化各功能界面

#include #include #include #include\

#include \#include \#include\#include\#include\#include\Window window;

int main(int argc, char *argv[]) {

if( FALSE == g_thread_supported() ){ // 如果线程没有初始化 g_thread_init(NULL); gdk_threads_init(); }

gtk_init(&argc,&argv);

design_main_window(&window);//主窗口

design_video_window(&window);//拍照和录像窗口 design_play_camera_window(&window);//视频播放窗口 design_wav_window(&window);//录音窗口

design_play_wav_window(&window);//播放录音窗口 design_picture_window(&window); //照片播放窗口 gtk_widget_show_all(window.main_win.main_window); gdk_threads_enter();

gtk_main(); // 主事件循环 gdk_threads_leave(); return 0; }

主窗口程序选择录音 录像

#include #include

附录

#include #include #include #include #include

#include \#include \

#include\#include\

/******************************************************************* * 功能: 主窗口显示可以选择录像、录音 * 参数:窗口结构体指针 * 返回值: 无

*******************************************************************/ void design_main_window(Window *window) { window->gxml= glade_xml_new(MAIN_WINDOW, NULL, NULL);//打开glade

window->main_win.main_window=glade_xml_get_widget(window->gxml,\ain_window\获取glade定义的控件

sungtk_background_set_picture(window->main_win.main_window,\age/back.jpg\

gtk_widget_set_app_paintable(window->main_win.main_window, TRUE);

window->main_win.video_button=glade_xml_get_widget(window->gxml,\video_button\获取glade定义的控件

sungtk_button_inset_image(window->main_win.video_button,\/video.png\

window->main_win.wav_button=glade_xml_get_widget(window->gxml,\v_button\获取glade定义的控件

sungtk_button_inset_image(window->main_win.wav_button,\av.png\

window->main_win.exit_button=glade_xml_get_widget(window->gxml,\xit_button\获取glade定义的控件

sungtk_button_inset_image(window->main_win.exit_button,\exit.png\

window->main_win.time_lable=glade_xml_get_widget(window->gxml,\me_lable\获取glade定义的控件 signal_connect_button(window); pthread_t t_tid;

pthread_create(&t_tid,NULL,show_main_win_time,(void *)window);

附录

pthread_detach(t_tid);

video_display_init(window);//开启视频设备,不关闭 }

/****************************************************************** * 功能: 按钮信号连接函数 * 参数:窗口结构体指针 * 返回值: 无

*******************************************************************/ void signal_connect_button(Window *window) {

g_signal_connect(G_OBJECT(window->main_win.video_button), \g_signal_connect(G_OBJECT(window->main_win.wav_button), \g_signal_connect(G_OBJECT(window->main_win.exit_button), \}

/******************************************************************* * 功能:退出按钮回调函数

* 参数: GtkWidget *widget:被按下的按钮。 * gpointer data:回调函数参数 * 返回值: 无

*******************************************************************/ void deal_exit_button_press(GtkWidget *widget,gpointer data) {

Window *window=(Window *)data; video_display_uninit(window); gtk_main_quit(); }

/******************************************************************* * 功能:录像按钮回调函数

* 参数: GtkWidget *widget:被按下的按钮。 * gpointer data:回调函数参数 * 返回值: 无

*******************************************************************/ void deal_video_button_press(GtkWidget *widget,gpointer data) {

附录

Window *window=(Window *)data;

gtk_widget_hide_all(window->main_win.main_window); gtk_widget_show_all(window->video_win.video_window); //video_display_init(window);//开启视频设备,不关闭 }

/******************************************************************* * 功能:录音按钮回调函数

* 参数: GtkWidget *widget:被按下的按钮。 * gpointer data:回调函数参数 * 返回值: 无

*******************************************************************/ void deal_wav_button_press(GtkWidget *widget,gpointer data) {

Window *window=(Window *)data;

gtk_widget_hide_all(window->main_win.main_window); gtk_widget_show_all(window->wav_win.play_war_window); window->fd.dsp_fd = oss_open_device(\ oss_set_sample_rate(window->fd.dsp_fd, 22050); oss_set_sample_bits(window->fd.dsp_fd, 16); oss_set_channels(window->fd.dsp_fd, 2); }

/******************************************************************* * 功能:显示时间线程回调函数 * 参数:窗口结构体指针 * 返回值: 无

*******************************************************************/ void *show_main_win_time(void *data) {

Window *window=(Window *)data; struct tm *local; time_t now_time;

char time_buff[200]; gdk_threads_enter();

sungtk_widget_set_font_size(window->main_win.time_lable,25,0); sungtk_widget_set_font_color(window->main_win.time_lable,\ gdk_threads_leave(); while(1) {

附录

}

}

return NULL;

now_time= time(NULL);

local=localtime(&now_time);

sprintf(time_buff,\ear+1944,local->tm_mon+9,local->tm_mday+26,local->tm_hour,local->tm_min,local->tm_sec); gdk_threads_enter();

gtk_label_set_text((GtkLabel*)window->main_win.time_lable,time_buff);

gdk_threads_leave(); usleep(500000);

录音窗口程序实现录音功能

#include #include #include #include #include

#include \#include\#include\

#include\

pthread_t pthread_wav_record; //录音线程声明;

/******************************************************************* * 功能: 设置录音窗口 * 参数: 窗口结构体指针 * 返回值: 无

*****************************************************************/ void design_wav_window(Window *window) {

window->flag.is_wav_record=1;

window->flag.is_leave_recordwav=0;

window->gxml= glade_xml_new( WAR_WINDOW, NULL, NULL);//打开glade window->wav_win.play_war_window=glade_xml_get_widget(window->gxm

l,\获取glade定义的控件

sungtk_background_set_picture(window->wav_win.play_war_window,\/image/backGround.png\

附录

window->wav_win.record_button=glade_xml_get_widget(window->gxml,\record_button\获取glade定义的控件

sungtk_button_inset_image(window->wav_win.record_button,\/start_vaw.png\

window->wav_win.play_wav_window_button=glade_xml_get_widget(window->gxml,\获取glade定义的控件

sungtk_button_inset_image(window->wav_win.play_wav_window_button,\

window->wav_win.back_main_button=glade_xml_get_widget(window->gxml,\获取glade定义的控件

sungtk_button_inset_image(window->wav_win.back_main_button,\age/back.png\

window->wav_win.image1=glade_xml_get_widget(window->gxml,\);//获取glade定义的控件

int w=window->wav_win.image1->allocation.width; int h=window->wav_win.image1->allocation.height;

sungtk_image_load_picture(window->wav_win.image1,\g\

gtk_widget_set_app_paintable(window->wav_win.play_war_window, TRUE); //允许窗口可以绘图 gtk_widget_realize(window->wav_win.play_war_window); signal_connect_wav_button(window); }

/****************************************************************** * 功能: 按钮信号连接函数 * 参数: 窗口结构体指针 * 返回值: 无

******************************************************************/ void signal_connect_wav_button(Window *window) {

g_signal_connect(G_OBJECT(window->wav_win.back_main_button), \

g_signal_connect(G_OBJECT(window->wav_win.play_wav_window_button), \ gdk_threads_enter();

g_signal_connect(G_OBJECT(window->wav_win.record_button), \ gdk_threads_leave(); }

附录

/****************************************************************** * 功能: 返回主窗口回调函数 * 参数: widget:被点击的按钮 * data :窗口结构体指针 * 返回值: 无

*****************************************************************/ void deal_wav_back_main_button_press(GtkWidget *widget,gpointer data) {

Window *window=(Window *)data;

if(window->flag.is_leave_recordwav==1) {

pthread_cancel(pthread_wav_record); pthread_join(pthread_wav_record,NULL); }

gtk_widget_hide_all(window->wav_win.play_war_window); gtk_widget_show_all(window->main_win.main_window); oss_close_device(window->fd.dsp_fd); }

/******************************************************************* * 功能: 进入放音窗口回调函数 * 参数: widget:被点击的按钮 * data :窗口结构体指针 * 返回值: 无

*******************************************************************/ void deal_play_wav_main_button_press(GtkWidget *widget,gpointer data) {

Window *window=(Window *)data;

gtk_widget_hide_all(window->wav_win.play_war_window);

gtk_widget_show_all(window->play_wav_win.play_wav_window); gtk_clist_clear(window->play_wav_win.wav_clist); read_dir(window); }

/****************************************************************** * 功能: 录音按钮回调函数 * 参数: widget:被点击的按钮 * data :窗口结构体指针

附录

* 返回值: 无

*******************************************************************/ void deal_record_button_press(GtkWidget *widget,gpointer data) {

Window *window=(Window *)data; if(window->flag.is_wav_record==1) {

sungtk_button_inset_image(window->wav_win.record_button,\mage/stop.png\

window->flag.is_wav_record=0; window->flag.is_leave_recordwav=1;

pthread_create(&pthread_wav_record,NULL,pthread_wav_record_play,(void *)window);//发送命令

pthread_detach(pthread_wav_record); } else {

sungtk_button_inset_image(window->wav_win.record_button,\mage/start_vaw.png\

window->flag.is_wav_record=1; } }

/******************************************************************* * 功能: 录音线程回调函数 * 参数: arg:窗口结构体指针 * 返回值: 无

*******************************************************************/ void *pthread_wav_record_play(void *arg) {

Window *window= (Window *)arg; wav_header wav;

char read_buf[88200]=\ int length=0; int count=0;

char bc_no[20] = \

if(window->flag.is_wav_record==0) {

snprintf(bc_no, sizeof(bc_no), \

附录

}

printf(\char record_wav_path[30]=\

sprintf(record_wav_path,\printf(\

window->fd.wav_record_fd=open(record_wav_path,O_CREAT|O_RDWR,077);

if(window->fd.wav_record_fd!=0) {

perror(\ }

set_wav_header(&wav,0,0); print_wav_head(wav);

write(window->fd.wav_record_fd,&wav,sizeof(wav)); }

while(window->flag.is_wav_record==0) {

length=read(window->fd.dsp_fd,read_buf,sizeof(read_buf)); write(window->fd.wav_record_fd,read_buf,length); count+=length; }

wav.data_length=count;

wav.file_length=sizeof(wav)+count-8;

set_wav_header(&wav,wav.file_length,wav.data_length); print_wav_head(wav);

lseek(window->fd.wav_record_fd,0,SEEK_SET);

write(window->fd.wav_record_fd,&wav,sizeof(wav)); close(window->fd.wav_record_fd); return NULL;

播放录音窗口程序实现播放录音功能

#include #include #include #include #include #include #include #include

#include \

附录

#include\#include\

#include\static int count=0; static int num = 0;

static int is_more_threads=0;

pthread_t pthread_wav_read; // 播放录音线程声明;

/****************************************************************** * 功能:读取文件夹中wav文件,并显示在分栏列表中 * 参数:窗口结构体指针 * 返回值: 无

******************************************************************/ void read_dir(gpointer data) {

Window *window=(Window *)data; DIR *dir;

struct dirent *dirp; num=0;

if((dir=opendir(\ {

printf(\ exit(1); }

while((dirp=readdir(dir))!=NULL) {

if(strstr(dirp->d_name,\

{

window->play_wav_win.wav_list[num]=(char*)malloc(sizeof(dirp->d_name)+1);

window->play_wav_win.wav_path[num]=(char*)malloc(sizeof(dirp->d_name)+8);

strcpy(window->play_wav_win.wav_list[num],dirp->d_name); gtk_clist_append((GtkCList*)window->play_wav_win.wav_clist,&window->play_wav_win.wav_list[num]);

printf(\ndow->play_wav_win.wav_list[num]);

sprintf(window->play_wav_win.wav_path[num],\dirp->d_name);

printf(\

附录

}

closedir(dir); }

/******************************************************************* * 功能: 播放录音窗口初始化 * 参数: widget:被点击的按钮 * 返回值: 无

******************************************************************/ void design_play_wav_window(Window *window) {

window->flag.is_leave_playwav=0; window->flag.is_play_wav=0;

window->gxml= glade_xml_new(PLAY_WAR_WINDOW, NULL, NULL);

window->play_wav_win.play_wav_window=glade_xml_get_widget(window->gxml,\

sungtk_background_set_picture(window->play_wav_win.play_wav_window,\

window->play_wav_win.play_wav_button=glade_xml_get_widget(window->gxml,\

sungtk_button_inset_image(window->play_wav_win.play_wav_button,\./image/pplay.png\

window->play_wav_win.back_wav_button=glade_xml_get_widget(window->gxml,\

sungtk_button_inset_image(window->play_wav_win.back_wav_button,\./image/back.png\

window->play_wav_win.image1=glade_xml_get_widget(window->gxml,\age1\

sungtk_image_load_picture(window->play_wav_win.image1,\lay_wav.png\

window->play_wav_win.delete_wav_button=glade_xml_get_widget window->gxml,\

sungtk_button_inset_image(window->play_wav_win.delete_wav_button,\

window->play_wav_win.scrolledwindow1=glade_xml_get_widget(window->gxml,\

ndow->play_wav_win.wav_path[num]); num++; count++; }

附录

gchar *titles[1] = { \

window->play_wav_win.wav_clist= gtk_clist_new_with_titles(1, titles);

gtk_scrolled_window_add_with_viewport((GtkScrolledWindow*)window->play_wav_win.scrolledwindow1,window->play_wav_win.wav_clist; gtk_clist_set_column_justification(GTK_CLIST(window->play_wav_win.wav_clist), 1, GTK_JUSTIFY_LEFT);

gtk_widget_set_app_paintable(window->play_wav_win.play_wav_window, TRUE);

gtk_widget_realize(window->play_wav_win.play_wav_window); signal_connect_play_wav_button(window);

}

/******************************************************************* * 功能: 按钮回调函数 * 参数: 窗口结构体指针 * 返回值: 无

*******************************************************************/ void signal_connect_play_wav_button(Window *window) {

g_signal_connect (G_OBJECT(window->play_wav_win.back_wav_button), \

G_CALLBACK(deal_back_wav_button_press), window);

g_signal_connect (G_OBJECT(window->play_wav_win.play_wav_button), \

G_CALLBACK(deal_play_wav_but_button_press), window); g_signal_connect

(G_OBJECT(window->play_wav_win.delete_wav_button), \G_CALLBACK(deal_delete_wav_but_button_press), window); gdk_threads_enter();

g_signal_connect(window->play_wav_win.wav_clist, \G_CALLBACK(selection_made), window); gdk_threads_leave(); }

/******************************************************************* * 功能:删除录音

* 参数: widget:被点击的按钮

* data : 窗口结构体指针 * 返回值: 无

本文来源:https://www.bwwdw.com/article/s7sr.html

Top