中国科学技术大学电子工程与信息科学系多媒体通信实验室(Copyright2002) PC-PC的P电话实验 一、实验目的 在一定程度上了解网络通信中多媒体通信的编程方法和基本思路。在我们的样本程序 中,对定义变量和函数调用有比较详细的注释,请同学们自己认真阅读。 二、预备知识 要求对Winsock编程和四年级多媒体课程中声卡实验有相当的了解。有关Winsock编 程的详细知识,请参阅实验“TCPP编程”的实验说明书:或参考文件“Winsock编程指南” (该文件摘自是BBS上“Winsock”版)。有关声卡编程的知识,目前多媒体实验室没有电 子版图书,请同学们自己到图书馆借阅相关的“多媒体编程”一类的书籍。 如果感觉到实验较困难,可与辅导老师协商做本科生“计算机网络实验”中“单向语音 传输实验”。该实验为本实验的简化版本。 三、实验原理 1、VC中用于描述波形文件格式的有关结构体定义 (1)结构体PCMWAVEFORMAT PCMWAVEFORMAT结构用于描述PCM结构波形数据的格式,其结构定义如下所示: typedef struct{ WAVEFORMAT wf; WORD wBitsPerSample; PCMWAVEFORMAT: 其中WbitsPerSample是采样率 其中wf为WAVEFORMAT结构,用于描述数据的一般结构信息,它包括了所有波形文件的 通用格式信息。结构定义如下所示: typedef struct{ WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系network@ustc.cdu.cn cxh@ustc.cdu.cn
中国科学技术大学电子工程与信息科学系 多媒体通信实验室(Copyright 2002) PC-PC 的 IP 电话实验 一、实验目的 在一定程度上了解网络通信中多媒体通信的编程方法和基本思路。在我们的样本程序 中,对定义变量和函数调用有比较详细的注释,请同学们自己认真阅读。 二、预备知识 要求对 Winsock 编程和四年级多媒体课程中声卡实验有相当的了解。有关 Winsock 编 程的详细知识,请参阅实验“TCP/IP 编程”的实验说明书;或参考文件“Winsock 编程指南” (该文件摘自是 BBS 上“Winsock”版)。有关声卡编程的知识,目前多媒体实验室没有电 子版图书,请同学们自己到图书馆借阅相关的“多媒体编程”一类的书籍。 如果感觉到实验较困难,可与辅导老师协商做本科生“计算机网络实验”中“单向语音 传输实验”。该实验为本实验的简化版本。 三、实验原理 1、VC 中用于描述波形文件格式的有关结构体定义 (1)结构体 PCMWAVEFORMAT PCMWAVEFORMAT 结构用于描述 PCM 结构波形数据的格式,其结构定义如下所示: typedef struct { WAVEFORMAT wf; WORD wBitsPerSample; } PCMWAVEFORMAT; 其中 WbitsPerSample 是采样率 其中 wf 为 WAVEFORMAT 结构,用于描述数据的一般结构信息,它包括了所有波形文件的 通用格式信息。结构定义如下所示: typedef struct { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系 network@ustc.edu.cn cxh@ustc.edu.cn
中国科学技术大学电子工程与信息科学系多媒体通信实验室(Copyright2002) WORD wBitsPerSample; WORD cbSize; }WAVEFORMATEX: 具体参数解释如下: wFormatTag 波形数据的格式,定义在MMREG.H文件中 nChannels 波形数据的通道数:单声道或立体声 nSamplesPerSec 采样率,对于PCM格式的波形数据,采样率有8.0kHz,11.025kHz,22.05kHz,and44.1kHz 等几种 nAvgBytesPerSec 数据率,对于PCM格式的波形数据,数据率等于采样率乘以每样点字节数 nBlockAlign 每个样点的字节数 wBitsPerSample 采样精度,对于PCM格式的波形数据,采样精度为8或16 cbSize 附加格式信息的数据块大小 (2)设备头结构VAVEHDR 结构WAVEHDR定义了指向波形数据缓冲区的设备头,具体定义如下: typedef struct{ LPSTR IpData: DWORD dwBufferLength; DWORD dwBytesRecorded; DWORD dwUser; DWORD dwFlags; DWORD dwLoops; struct wavehdr tag lpNext: DWORD reserved; }WAVEHDR; IpData 波形数据的缓冲区地址 dwBufferLength 波形数据的缓冲区地址的长度 dwBytesRecorded当设备用于录音时,标志己经录入的数据长度 dwUser 用户数据 dwFlags 波形数据的缓冲区的属性 dwLoops 播放循环的次数,仅用于播放控制中 IpNext和reserved均为保留值 注意:参考VC中mmsystem.h文件中的有关定义可以知道,PWAVEHDR, NPWAVEHDR,LPWAVEHDR,LPHWAVEIN均定义为指向结构WAVEHDR的指针。在实验 的样本程序中,用到下列有关多媒体的结构:“HWAVEIN”、“LPWAVEHDR”、 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系network@ustc.cd山.cn cxh@ustc.cdu.cn
中国科学技术大学电子工程与信息科学系 多媒体通信实验室(Copyright 2002) WORD wBitsPerSample; WORD cbSize; } WAVEFORMATEX; 具体参数解释如下: wFormatTag 波形数据的格式,定义在 MMREG.H 文件中 nChannels 波形数据的通道数:单声道或立体声 nSamplesPerSec 采样率,对于 PCM 格式的波形数据,采样率有 8.0 kHz, 11.025 kHz, 22.05 kHz, and 44.1 kHz 等几种 nAvgBytesPerSec 数据率,对于 PCM 格式的波形数据,数据率等于采样率乘以每样点字节数 nBlockAlign 每个样点的字节数 wBitsPerSample 采样精度,对于 PCM 格式的波形数据,采样精度为 8 或 16 cbSize 附加格式信息的数据块大小 (2)设备头结构 WAVEHDR 结构 WAVEHDR 定义了指向波形数据缓冲区的设备头,具体定义如下: typedef struct { LPSTR lpData; DWORD dwBufferLength; DWORD dwBytesRecorded; DWORD dwUser; DWORD dwFlags; DWORD dwLoops; struct wavehdr_tag * lpNext; DWORD reserved; } WAVEHDR; lpData 波形数据的缓冲区地址 dwBufferLength 波形数据的缓冲区地址的长度 dwBytesRecorded 当设备用于录音时,标志已经录入的数据长度 dwUser 用户数据 dwFlags 波形数据的缓冲区的属性 dwLoops 播放循环的次数,仅用于播放控制中 lpNext 和 reserved 均为保留值 注意: 参 考 VC 中 mmsystem.h 文件中的有 关定义可以知道,PWAVEHDR, NPWAVEHDR, LPWAVEHDR,LPHWAVEIN 均定义为指向结构 WAVEHDR 的指针。在实验 的样本程序中, 用到下列有关多媒体 的结构:“ HWAVEIN ”、“ LPWAVEHDR ”、 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系 network@ustc.edu.cn cxh@ustc.edu.cn
中国科学技术大学电子工程与信息科学系多媒体通信实验室(Copyright2002) “MMRESULT”。 2、样本程序的设计思路 (1)样本程序的基本思路 本实验样本程序的基本思路是:发送端将录入的声音分时打包发送:接收端将收到的 P包逐个播放。实验室给出的样本程序有2个文件:SendVoice目录下的项目文件用于录入 并发送声音、Recieve Voice目录下的项目文件用于接收并播放声音。整个程序建立在TCPP 编程的技术之上,思路非常简单:初始化$OCKET、初始化声音设备、开始录音,然后由 WINDOWS自动发出的缓冲区满的消息控制发送。在程序结束时,并没有将所有打开的设 备关闭,希望同学们在实验过程中能够将程序结束的清理部分内容添入。 (2)发送程序中有关声音的参数 程序中有关声音的参数定义如下: char pInBuffer1; /录音缓冲区1(char) char pInBuffer2; /录音缓冲区2(char) HWAVEIN hWaveln; 录音设备标志 LPWAVEHDR pWaveHdrl; ∥设备设置头1 LPWAVEHDR pWaveHdr2; ∥设备设置头2 MMRESULT result: ∥函数返回值 PCMWAVEFORMAT pcm; /∥波形数据格式 BOOL m RecFirst; 缓冲区使用标志 以上用到的结构体在实验原理的第一部分中有较为简洁的说明。如果看完了实验原理第 一部分以后仍然对WINDOWS中有关多媒体部分的结构定义不太清楚的话,请仔细阅读VC 中的相关帮助或到查询其他有关的书籍。 在程序的初始化部分对声音采样的有关参数进行赋值 //Format of voice:16 bits,11.025kHz,mono audio pcm.wf.wFormatTag=-WAVE FORMAT PCM;∥格式为PCM pcm.wf.nChannels=1; ∥单声道mono pcm.wf.nSamplesPerSec=8000; ∥采样率 pcm.wf.nAvgBytesPerSec=8000*2; /数据率 pcm.wf.nBlockAlign=2; 侮样点的字节数 pcm.wBitsPerSample=16; ∥采样精度 并且分配缓冲区所需要的内存 绿音设备头的初始化 pWaveHdr1 =(LPWAVEHDR)GlobalAllocPtr(GHNDIGMEM SHARE,sizeof(WAVEHDR)): pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHNDIGMEM SHARE,sizeof(WAVEHDR)); 录音缓冲区 pInBufferl =(char *)GlobalAllocPtr(GHNDGMEM SHARE.PCMBUFFER SIZE): 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系network@ustc.cdu.cn cxh@ustc.cdu.cn
中国科学技术大学电子工程与信息科学系 多媒体通信实验室(Copyright 2002) “ MMRESULT”。 2、样本程序的设计思路 (1)样本程序的基本思路 本实验样本程序的基本思路是:发送端将录入的声音分时打包发送;接收端将收到的 IP 包逐个播放。实验室给出的样本程序有 2 个文件:SendVoice 目录下的项目文件用于录入 并发送声音、RecieveVoice 目录下的项目文件用于接收并播放声音。整个程序建立在 TCP/IP 编程的技术之上,思路非常简单:初始化 SOCKET、初始化声音设备、开始录音,然后由 WINDOWS 自动发出的缓冲区满的消息控制发送。在程序结束时,并没有将所有打开的设 备关闭,希望同学们在实验过程中能够将程序结束的清理部分内容添入。 (2)发送程序中有关声音的参数 程序中有关声音的参数定义如下: char pInBuffer1; //录音缓冲区 1(char) char pInBuffer2; //录音缓冲区 2(char) HWAVEIN hWaveIn; //录音设备标志 LPWAVEHDR pWaveHdr1; //设备设置头 1 LPWAVEHDR pWaveHdr2; //设备设置头 2 MMRESULT result; //函数返回值 PCMWAVEFORMAT pcm; //波形数据格式 BOOL m_RecFirst; //缓冲区使用标志 以上用到的结构体在实验原理的第一部分中有较为简洁的说明。如果看完了实验原理第 一部分以后仍然对 WINDOWS 中有关多媒体部分的结构定义不太清楚的话,请仔细阅读 VC 中的相关帮助或到查询其他有关的书籍。 在程序的初始化部分对声音采样的有关参数进行赋值 //Format of voice: 16 bits,11.025kHz,mono audio pcm.wf.wFormatTag=WAVE_FORMAT_PCM; //格式为 PCM pcm.wf.nChannels=1; //单声道 mono pcm.wf.nSamplesPerSec=8000; //采样率 pcm.wf.nAvgBytesPerSec=8000*2; //数据率 pcm.wf.nBlockAlign=2; //每样点的字节数 pcm.wBitsPerSample=16; //采样精度 并且分配缓冲区所需要的内存 //录音设备头的初始化 pWaveHdr1 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); //录音缓冲区 pInBuffer1 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系 network@ustc.edu.cn cxh@ustc.edu.cn
中国科学技术大学电子工程与信息科学系多媒体通信实验室(Copyright2002) pInBuffer2 =(char *)GlobalAllocPtr(GHNDIGMEM SHARE,PCMBUFFER SIZE); ∥初始化缓冲区控制变量,首先使用第一个缓冲区 m RecFirst=TRUE 在录音过程中用了两个录音缓冲区pInBuffer1、pInBuffer2,大小都是360*8。录音过程 中轮流使用pInBuffer1和pInBuffer2.,通过存取BOOL变量m_RecFirst来标志正在使用的是 哪一个录音缓冲区。 (3)接收程序中有关声音的参数 程序中有关声音的参数定义如下: char pOutBufferl; 川放音缓冲区1 char pOutBuffer2: ∥放音缓冲区2 char rBuffer; /接收缓冲区No USE HWAVEOUT hWaveOut: 录音设备标志 LPWAVEHDR pWaveHdrl; ∥设备设置头1 LPWAVEHDR pWaveHdr2: /∥设备设置头2 MMRESULT result: PCMWAVEFORMAT pcm; 波形数据格式 BOOL m PlayFirst: 缓冲区使用标志 以上用到的结构体在实验原理的第一部分中有较为简洁的说明。如果看完了实验原理第 一部分以后仍然对WINDOWS中有关多媒体部分的结构定义不太清楚的话,请仔细阅读VC 中的相关帮助或到查询其他有关的书籍。 在程序的初始化部分对声音采样的有关参数进行赋值 //Format of voice:16 bits,11.025kHz,mono audio pcm.wf.wFormatTag=WAVE FORMAT PCM;∥格式为PCM pcm.wf.nChannels=1; /单声道mono pcm.wf.nSamplesPerSec=8000: /采样率 pcm.wf.nAvgBytesPerSec=8000*2: /数据率 pcm.wf.nBlockAlign=2; ∥每样点的字节数 pcm.wBitsPerSample=16; 采样精度 并且分配缓冲区所需要的内存 pWaveHdrl=(LPWAVEHDR)GlobalAllocPtr(GHNDJGMEM SHARE.sizeof(WAVEHDR)): pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHNDIGMEM SHARE,sizeof(WAVEHDR)); ∥放音缓冲区 pOutBufferl =(char *)GlobalAllocPtr(GHNDIGMEM SHARE,PCMBUFFER SIZE); pOutBuffer2 =(char *)GlobalAllocPtr(GHNDIGMEM SHARE.PCMBUFFER SIZE): 接收缓冲区 rBuffer =(char *)GlobalAllocPtr(GHNDGMEM SHARE.PCMBUFFER SIZE): 初始化缓冲区控制变量,首先使用第一个缓冲区 m PlayFirst=TRUE: 在放音过程中用了两个放音缓冲区pOutBuffer1、pOutBuffer2,大小都是360*8。录音 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系network@ustc.edu.cn cxh@ustc.cdu.cn
中国科学技术大学电子工程与信息科学系 多媒体通信实验室(Copyright 2002) pInBuffer2 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); //初始化缓冲区控制变量,首先使用第一个缓冲区 m_RecFirst=TRUE; 在录音过程中用了两个录音缓冲区 pInBuffer1、pInBuffer2,大小都是 360*8。录音过程 中轮流使用 pInBuffer1 和 pInBuffer2,通过存取 BOOL 变量 m_RecFirst 来标志正在使用的是 哪一个录音缓冲区。 (3) 接收程序中有关声音的参数 程序中有关声音的参数定义如下: char * pOutBuffer1; //放音缓冲区 1 char * pOutBuffer2; //放音缓冲区 2 char * rBuffer; //接收缓冲区 No USE HWAVEOUT hWaveOut; //录音设备标志 LPWAVEHDR pWaveHdr1; //设备设置头 1 LPWAVEHDR pWaveHdr2; //设备设置头 2 MMRESULT result; PCMWAVEFORMAT pcm; //波形数据格式 BOOL m_PlayFirst; //缓冲区使用标志 以上用到的结构体在实验原理的第一部分中有较为简洁的说明。如果看完了实验原理第 一部分以后仍然对 WINDOWS 中有关多媒体部分的结构定义不太清楚的话,请仔细阅读 VC 中的相关帮助或到查询其他有关的书籍。 在程序的初始化部分对声音采样的有关参数进行赋值 //Format of voice: 16 bits,11.025kHz,mono audio pcm.wf.wFormatTag=WAVE_FORMAT_PCM; //格式为 PCM pcm.wf.nChannels=1; //单声道 mono pcm.wf.nSamplesPerSec=8000; //采样率 pcm.wf.nAvgBytesPerSec=8000*2; //数据率 pcm.wf.nBlockAlign=2; //每样点的字节数 pcm.wBitsPerSample=16; //采样精度 并且分配缓冲区所需要的内存 pWaveHdr1 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); //放音缓冲区 pOutBuffer1 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); pOutBuffer2 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); //接收缓冲区 rBuffer =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); //初始化缓冲区控制变量,首先使用第一个缓冲区 m_PlayFirst=TRUE; 在放音过程中用了两个放音缓冲区 pOutBuffer1、pOutBuffer2,大小都是 360*8。录音 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系 network@ustc.edu.cn cxh@ustc.edu.cn
中国科学技术大学电子工程与信息科学系多媒体通信实验室(Copyright2002) 过程中轮流使用pOutBuffer1和pOutBuffer22,通过存取BOOL变量m PlayFirst来标志正在 使用的是哪一个录音缓冲区。 注意:在样本程序中,需要将stdlib.h、malloc.h、wondowsx.h、mmsystem.h四个头文 件包含进项目,并且需要在项目的连接设置中将库mmwin.lib连接入项目。 四、实验要求 1.实验2人一组或一人在本机上自行操作演示。实验样本程序发送和接收是两个独立 的程序,但均具备发送和接收两项功能,需要在实验过程中更改P地址、端口号等基本信 息,修改方法参见实验代码目录中的说明文件。编写自己的程序集成发送和接收功能。由辅 导老师或实验室当值老师检查通过。 五、思考题 1.WINDOWS下SOCKET编程中阻塞方式和非阻塞方式有什么区别?在你的程序中采 用的是哪中方式?为什么采用这种方式? 2.波形文件的格式定义包括哪些部分?在VC中有那些结构体定义与之相对应?这些 结构体是在哪个头文件中声明的? 3.为了保证发送实时的声音,在实验的样本程序中采用双缓冲区的结构,为什么?你 采用的是什么办法?阅读有关的联机帮助或文献,是否有更好的办法?怎样实现? 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系network@ustc.cdu.cn cxh@ustc.cdu.cn
中国科学技术大学电子工程与信息科学系 多媒体通信实验室(Copyright 2002) 过程中轮流使用 pOutBuffer1 和 pOutBuffer2,通过存取 BOOL 变量 m_PlayFirst 来标志正在 使用的是哪一个录音缓冲区。 注意:在样本程序中,需要将 stdlib.h、malloc.h、wondowsx.h、mmsystem.h 四个头文 件包含进项目,并且需要在项目的连接设置中将库 mmwin.lib 连接入项目。 四、实验要求 1. 实验 2 人一组或一人在本机上自行操作演示。实验样本程序发送和接收是两个独立 的程序,但均具备发送和接收两项功能,需要在实验过程中更改 IP 地址、端口号等基本信 息,修改方法参见实验代码目录中的说明文件。编写自己的程序集成发送和接收功能。由辅 导老师或实验室当值老师检查通过。 五、思考题 1. WINDOWS 下 SOCKET 编程中阻塞方式和非阻塞方式有什么区别?在你的程序中采 用的是哪中方式?为什么采用这种方式? 2. 波形文件的格式定义包括哪些部分?在 VC 中有那些结构体定义与之相对应?这些 结构体是在哪个头文件中声明的? 3. 为了保证发送实时的声音,在实验的样本程序中采用双缓冲区的结构,为什么?你 采用的是什么办法?阅读有关的联机帮助或文献,是否有更好的办法?怎样实现? 如果您在阅读过程中发现疏漏和错误,请您尽快和编者取得联系 network@ustc.edu.cn cxh@ustc.edu.cn