📄 deviceclass.old
字号:
delete [] pNumber[i];
pNumber[i]=NULL;
nNumber[i]=0;
continue;
}
}
}
}
// 读取“一路顺风”声音文件,该文件名称必须为THANKYOU.WAV
memset(pFullPath,0,130);
sprintf(pFullPath,"%sTHANKYOU.WAV",pDir);
i=GetSoundLen(pFullPath);
if(i!=0){
if((pThankYou=new char[i])!=NULL){
if(!LoadSound(pFullPath,pThankYou,i)){
delete [] pThankYou;
pThankYou=NULL;
}
}
}
// 读取“免费”声音文件,该文件名称必须为FREE.WAV
memset(pFullPath,0,130);
sprintf(pFullPath,"%sFREE.WAV",pDir);
nFree=GetSoundLen(pFullPath);
if(nFree!=0){
if((pFree=new char[nFree])!=NULL){
if(!LoadSound(pFullPath,pFree,nFree)){
delete [] pFree;
pFree=NULL;
nFree=0;
}
}
}
// 读取声音间隔文件,该文件名称为SPACE.WAV
memset(pFullPath,0,130);
sprintf(pFullPath,"%sSPACE.WAV",pDir);
nSpace=GetSoundLen(pFullPath);
if(nSpace!=0){
if((pSpace=new char[nSpace])!=NULL){
if(!LoadSound(pFullPath,pSpace,nSpace)){
delete [] pSpace;
pSpace=NULL;
nSpace=0;
}
}
}
}
// 播放语音价格
void CSound::PlayFare()
{
// 首先计算要合成声音的长度,根据该长度分配内存
UINT nSoundLen; //存储要播放的数据长度
nSoundLen=nClass; //“车型”声音文件
CTransInfo m_clsTrans;
int nBusClass=m_clsTrans.BusClass();
if(nBusClass<0) nBusClass=0;
nSoundLen+=nNumber[nBusClass]; //车型数字声音文件
nSoundLen+=nSpace; //车型和金额之间增加空格
int nValue=m_clsTrans.Fare()/1000;
// 获取当前车型声音文件长度
if(nValue>0){ //累计千位数字声音长度
nSoundLen+=nNumber[nValue%10];
nSoundLen+=nNumber[12]; //累计“千”声音长度
}
nValue=(m_clsTrans.Fare()%1000)/100;
if(nValue>0){ //累计百位数字声音长度
nSoundLen+=nNumber[nValue];
nSoundLen+=nNumber[11]; //累计“百”声音长度
} else {
// 假如千位和十位不为零但百位为0,累加声音“零”
if((m_clsTrans.Fare()/1000!=0)
&&(m_clsTrans.Fare()%100/10)!=0){
nSoundLen+=nNumber[0];
}
}
nValue=(m_clsTrans.Fare()%100)/10;
if(nValue>0){ //累计十位数字声音长度
nSoundLen+=nNumber[nValue];
nSoundLen+=nNumber[10]; //累计“十”声音长度
} else {
// 假如千位或百位不为零且个位不为0,累加声音“零”
if((m_clsTrans.Fare()/100!=0)
&&(m_clsTrans.Fare()%10!=0)){
nSoundLen+=nNumber[0];
}
}
nValue=m_clsTrans.Fare()%10;
switch(nValue){
case 0:
// 假如应收金额为0,合成“免费”;否则不合成
if(m_clsTrans.Fare()==0){
nSoundLen+=nFree; //累计“免费”声音长度
}
break;
case 2:
// 假如应收金额为两圆,合成“两”;否则合成“二”
if(m_clsTrans.Fare()==2){
nSoundLen+=nNumber[13]; //累计“两”声音文件长度
} else {
nSoundLen+=nNumber[nValue]; //累计“二”声音文件长度
}
break;
default:
nSoundLen+=nNumber[nValue];
break;
}
nSoundLen+=nRMB; //累计“圆”声音文件
// 根据要合成的声音长度申请内存
pSoundImage=new char[nSoundLen];
if(pSoundImage==NULL){
SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"合成声音文件时内存不足");
return;
}
memset(pSoundImage,0,nSoundLen);
// 合成车型声音文件
memmove(pSoundImage,pClass,nClass);
AssembleSound(pNumber[nBusClass],pSoundImage);
// 在车型和金额之间增加空格
AssembleSound(pSpace,pSoundImage);
// 合成千位声音文件
nValue=m_clsTrans.Fare()/1000;
if(nValue>0){ //累计千位数字声音长度
AssembleSound(pNumber[nValue%10],pSoundImage);
AssembleSound(pNumber[12],pSoundImage);
}
// 合成百位声音文件
nValue=(m_clsTrans.Fare()%1000)/100;
if(nValue>0){ //累计百位数字声音长度
AssembleSound(pNumber[nValue],pSoundImage);
AssembleSound(pNumber[11],pSoundImage);
} else {
// 假如千位和十位不为零但百位为0,累计声音“零”
if((m_clsTrans.Fare()/1000!=0)&&
((m_clsTrans.Fare()%100)/10!=0)){
AssembleSound(pNumber[0],pSoundImage);
}
}
// 合成十位声音文件
nValue=(m_clsTrans.Fare()%100)/10;
if(nValue>0){ //累计十位数字声音长度
AssembleSound(pNumber[nValue],pSoundImage);
AssembleSound(pNumber[10],pSoundImage);
} else {
// 假如千位或百位不为零且个位不为零但十位为零,累计声音“零”
if((m_clsTrans.Fare()/100!=0)&&
(m_clsTrans.Fare()%10!=0)){
AssembleSound(pNumber[0],pSoundImage);
}
}
nValue=m_clsTrans.Fare()%10;
switch(nValue){
case 0:
// 假如应收金额为0,合成“免费”;否则不合成
if(m_clsTrans.Fare()==0){
AssembleSound(pFree,pSoundImage);
}
break;
case 2:
// 假如应收金额为两圆,合成“两”;否则合成“二”
if(m_clsTrans.Fare()==2){
AssembleSound(pNumber[13],pSoundImage);
} else {
AssembleSound(pNumber[nValue],pSoundImage);
}
break;
default:
AssembleSound(pNumber[nValue],pSoundImage);
break;
}
// 累计“圆”声音文件
if(m_clsTrans.Fare()!=0){
AssembleSound(pRMB,pSoundImage);
}
try{
sndPlaySound(pSoundImage,SND_MEMORY|SND_ASYNC);
// 启动定时器,定时器超时后清除合成的声音数据
// 合成的声音文件播放时间 = 数据长度 / 每秒的字节数,对WAV
// 文件,每秒的字节数固定位于第29 - 32字节
DWORD nAvgBytesPerSec=0;
memmove(&nAvgBytesPerSec,pSoundImage+28,sizeof(DWORD));
DWORD nTotalTime=nSoundLen*1000/nAvgBytesPerSec+200;
SendMessage(theApp.m_pMainWnd->m_hWnd,WM_STARTUP_TIMER,SOUND_TIMER,nTotalTime);
}
catch(...){
SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CSound::PlayFare()出现异常\n");
}
}
// 定时器超时后删除合成的声音数据
void CSound::ProcessTimerOut()
{
if(pSoundImage!=NULL){
delete [] pSoundImage;
pSoundImage=NULL;
}
}
// 播放“祝您一路顺风”
void CSound::PlayThankYou()
{
try{
sndPlaySound(pThankYou,SND_MEMORY|SND_ASYNC);
}
catch(...){
SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CSound::PlayThankYou()出现异常\n");
}
}
// 停止播放
void CSound::StopPlay()
{
try{
sndPlaySound(NULL,SND_ASYNC);
}
catch(...){
SendMessage(theApp.m_pMainWnd->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CSound::StopPlay()出现异常\n");
}
}
// 按照实际情况重新组合并生成新的WAV文件
// WAV文件结构应当如下所述:
// 1、Microsoft WAV文件实际上是RIFF(Resource Intercharge File
// Format)数据块,RIFF数据块由四字节的标识符(对Microsoft
// WAV文件,为RIFF)、四字节的数据块尺寸(不包括4字节的标识符、
// 4字节的尺寸本身及文件未的填充字符。典型地:若文件尾无填充
// 字符,其值等于文件长度减8)、块的数据部分、填充字符(假如
// 数据长度为奇数,增加一个空字符作为占位符)
// 2、对Microsoft WAV文件,RIFF块的数据部分的前4个字节为WAVE,
// 指明本RIFF块的数据格式
// 3、RIFF块内可包含几种子块:"fmt "子块、"fact"子块及"data"子块,
// 其中"fact"子块并非必须
// 4、子块和RIFF块有相同的结构:四字节标识符、四字节数据块尺寸、
// 块的数据部分、填充字符
// 5、"fmt "块定义音频文件的格式,四字节标识符为"fmt ",数据长度
// 为以下结构的长度(若cbSize被忽略,则为16;否则为18),其数
// 据块定义音频文件格式,内容如下:
// typedef struct {
// WORD wFormatTag; 对Microsoft WAV文件,为1
// WORD nChannels; 声道数:单声道为1,双声道为2
// DWORD nSamplesPerSec; 每秒的样本数
// DWORD nAvgBytesPerSec; 每秒的字节数=每秒的样本数*每个数据块的尺寸
// WORD nBlockAlign; 每个数据块的尺寸=通道数*每个样本的字节数
// WORD wBitsPerSample; 每个样本的位数
// WORD cbSize; 指明附加在WAVEFORMATEX结构后的信息。若无附加信息,该字节应置0。对Microsoft WAV文件,该字可定义,也可被忽略
// } WAVEFORMATEX;
// 6、"fact"块存储实际数据样本长度(并非必须),四字节标识符为
// "fact",数据长度一般为4字节,数据块内容为波形样本的实际长度
// 7、"data"块存储实际的波形文件的实际长度,四字节标识符为"data",
// 数据长度为波形数据的实际长度(若存在"fact"块,则"data"的数据
// 长度等于"fact"块的数据块内容*每个样本所占字节数),数据块内
// 容即为实际的波形数据
void CSound::AssembleSound(char *pSrc,char *pObj)
{
// 首先判断入口参数是否合法的WAV数据
if((pSrc==NULL)||(pObj==NULL)) return;
DWORD nScrIndex=0;
DWORD nObjIndex=0;
// 合法WAV文件的前4个字节必须为RIFF,第9字节开始的8字节必须为WAVEfmt
if(strncmp(pSrc+nScrIndex,"RIFF",4)!=0) return;
if(strncmp(pObj+nObjIndex,"RIFF",4)!=0) return;
nScrIndex+=4;
nObjIndex+=4;
DWORD nFilePosition=nObjIndex;
DWORD nScrFileLen=ByteToDWORD(pSrc+nScrIndex);
DWORD nObjFileLen=ByteToDWORD(pObj+nObjIndex);
nScrIndex+=4;
nObjIndex+=4;
if(strncmp(pSrc+nScrIndex,"WAVEfmt ",8)!=0) return;
if(strncmp(pObj+nObjIndex,"WAVEfmt ",8)!=0) return;
nScrIndex+=8;
nObjIndex+=8;
// 读取fmt数据长度
DWORD nScrFmtLen=ByteToDWORD(pSrc+nScrIndex);
DWORD nObjFmtLen=ByteToDWORD(pObj+nObjIndex);
nScrIndex+=4;
nObjIndex+=4;
// 读取声音文件格式字段并判断要合并数据格式是否相同
WAVEFORMATEX structWave1,structWave2;
memmove(&structWave1,pSrc+nScrIndex,sizeof(WAVEFORMATEX));
memmove(&structWave2,pObj+nObjIndex,sizeof(WAVEFORMATEX));
if((structWave1.wFormatTag!=1)||(structWave2.wFormatTag!=1)) return;
if(structWave1.nChannels!=structWave2.nChannels) return;
if(structWave1.nSamplesPerSec!=structWave2.nSamplesPerSec) return;
if(structWave1.nAvgBytesPerSec!=structWave2.nAvgBytesPerSec) return;
if(structWave1.nBlockAlign!=structWave2.nBlockAlign) return;
if(structWave1.wBitsPerSample!=structWave2.wBitsPerSample) return;
// 检查是否有fact块,假如有,跳过该块的数据
nScrIndex+=nScrFmtLen;
nObjIndex+=nObjFmtLen;
if(strncmp(pSrc+nScrIndex,"fact",4)==0){
nScrIndex+=4;
nScrFmtLen=ByteToDWORD(pSrc+nScrIndex);
nScrIndex=nScrIndex+4+nScrFmtLen;
}
if(strncmp(pObj+nObjIndex,"fact",4)==0){
nObjIndex+=4;
nObjFmtLen=ByteToDWORD(pObj+nObjIndex);
nObjIndex=nObjIndex+4+nObjFmtLen;
}
// 检查是否为数据块,若否,说明文件格式错误,直接返回
if(strncmp(pSrc+nScrIndex,"data",4)!=0) return;
if(strncmp(pObj+nObjIndex,"data",4)!=0) return;
nScrIndex+=4;
nObjIndex+=4;
DWORD nDataPosition=nObjIndex;
// 读取有效数据长度
nScrFmtLen=ByteToDWORD(pSrc+nScrIndex);
nObjFmtLen=ByteToDWORD(pObj+nObjIndex);
// 将源数据连接到目标数据后面
nScrIndex+=4; //指向源有效数据其始位置
nObjIndex=nObjIndex+4+nObjFmtLen; //指向目标有效数据结束位置
memmove(pObj+nObjIndex,pSrc+nScrIndex,nScrFmtLen);
// 改变文件长度及有效数据长度
nObjFileLen+=nScrFmtLen;
nObjFmtLen+=nScrFmtLen;
// 假如数据长度为奇数,增加一填充符
// 以下几行导致声音文件播放时出现“波、波”声,故删除之
// if(nObjFmtLen%2!=0){
// nObjFileLen++;
// nObjFmtLen++;
// }
// 修改新生成数据的文件长度及有效数据长度
memmove(pObj+nFilePosition,&nObjFileLen,sizeof(DWORD));
memmove(pObj+nDataPosition,&nObjFmtLen,sizeof(DWORD));
}
UINT CSound::GetSoundLen(char *pFileName)
{
struct _finddata_t strFileInfo;
long hFile;
UINT nLen=0;
if((hFile=_findfirst(pFileName,&strFileInfo))!=-1L){
_findclose(hFile);
nLen=strFileInfo.size;
}
return nLen;
}
BOOL CSound::LoadSound(char *pFileName,char *pPointer,UINT nLen)
{
BOOL bSuccessFlag=FALSE;;
FILE *fp1;
if(pPointer==NULL) return bSuccessFlag;
memset(pPointer,0,nLen);
if((fp1=fopen(pFileName,"rb"))!=NULL){
fread(pPointer,1,nLen,fp1);
fclose(fp1);
bSuccessFlag=TRUE;
}
return bSuccessFlag;
}
// 将分字节存放的整数(4 byte)恢复成UINT
DWORD CSound::ByteToDWORD(char *pStr)
{
DWORD nValue=0;
memmove(&nValue,pStr,sizeof(DWORD));
return nValue;
}
// 释放声音文件所占用内存
void CSound::ReleaseDevice()
{
if(pClass!=NULL){
delete [] pClass;
pClass=NULL;
}
if(pRMB!=NULL){
delete [] pRMB;
pRMB=NULL;
}
for(int i=0;i<14;i++){
if(pNumber[i]!=NULL){
delete [] pNumber[i];
pNumber[i]=NULL;
}
}
if(pThankYou!=NULL){
delete [] pThankYou;
pThankYou=NULL;
}
if(pFree!=NULL){
delete [] pFree;
pFree=NULL;
}
if(pSpace!=NULL){
delete [] pSpace;
pSpace=NULL;
}
}
char CPrinter::chPrinterStatus;
BOOL CPrinter::bNormalFlag;
CPrinter::CPrinter()
{
}
// 打印机初始化:清空打印缓冲区的数据
void CPrinter::Initial()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -