⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 haudio.cpp

📁 VC++高级编程技巧与示例
💻 CPP
字号:
// HAudio.cpp: implementation of the CAudio class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HAudio.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAudio::CAudio()
{
	m_PlayType=0;
	m_pWnd=0;
	m_DvcID=0;
}

CAudio::~CAudio()
{
}

//打开一个音频文件:
BOOL CAudio::Open(unsigned int playtype,CString fn,CWnd * pwin)
{
	m_pWnd=pwin;
	m_PlayType=playtype;
	m_FileName=fn;
	unsigned long re;
	//打开文件:
	MCI_OPEN_PARMS OpenParms;
	switch(m_PlayType)
	{
		case _PLAYMIDI:
			{
				//MIDI类型的文件:
				OpenParms.lpstrDeviceType =(LPCSTR) MCI_DEVTYPE_SEQUENCER;
				OpenParms.lpstrElementName=(LPCSTR) m_FileName;
				break;
			}
		case _PLAYWAV:
			{
				//打开WAV类型的文件:
				OpenParms.lpstrDeviceType =(LPCSTR)MCI_DEVTYPE_WAVEFORM_AUDIO;
				OpenParms.lpstrElementName= m_FileName;
				break;
			}
		case _PLAYCD:
			{
				//播放CD:
				OpenParms.lpstrDeviceType =(LPCSTR) MCI_DEVTYPE_CD_AUDIO;
				break;
			}
		default:
			{
				AfxMessageBox("所指定的播放方式有误!");
				return FALSE;
			}
	}
	OpenParms.wDeviceID=0;
	if(m_PlayType==_PLAYCD)
	{
		re=mciSendCommand(NULL,
				MCI_OPEN,MCI_WAIT|
				MCI_OPEN_TYPE|
   				MCI_OPEN_TYPE_ID,
				(DWORD)(LPVOID) &OpenParms
				);
	}
	else
	{
		re=mciSendCommand(NULL,
				MCI_OPEN,MCI_WAIT|
				MCI_OPEN_TYPE|
   				MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT,
				(DWORD)(LPVOID) &OpenParms
				);
	}
	m_DvcID=OpenParms.wDeviceID;
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//关闭文件:
BOOL CAudio::Close()
{
	int re;
	re=mciSendCommand (m_DvcID, MCI_CLOSE, NULL, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//播放文件:
BOOL CAudio::Play(int minutes,int seconds,int frames)
{
	if(m_PlayType==_PLAYMIDI||m_PlayType==_PLAYWAV)
	{
		//保存旧的时间格式:
		DWORD oldtf;
		unsigned long re;
		oldtf=GetTimeFormat();
		//设置MSF时间格式:
		SetTimeFormat(MCI_FORMAT_MILLISECONDS);
		//设置当前位置:
		MCI_PLAY_PARMS pp;
		pp.dwFrom=(minutes*60+seconds)*1000;
		pp.dwCallback=(DWORD)m_pWnd->m_hWnd;
		re=mciSendCommand(m_DvcID,MCI_PLAY,MCI_FROM,
						  (DWORD)(LPVOID)&pp);
		if(re)
		{
			throw new CAudioException(re);
			return FALSE;
		}
		//恢复原来的时间格式:
		if(oldtf!=MCI_FORMAT_MSF)
		{
			SetTimeFormat(oldtf);
		}
		return TRUE;
	}
	else
	{
		AfxMessageBox("该函数仅供播放MIDI或Wave文件用!");
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::PlayCD(DWORD track, DWORD minute, DWORD second, DWORD frame)
{
	int re;
	if(m_PlayType==_PLAYCD)
	{
		//保存原来的时间格式:
		DWORD oldtf;
		oldtf=GetTimeFormat();
		//设置时间格式:
		SetTimeFormat(MCI_FORMAT_TMSF);
		//开始播放CD(一次只播放一个):
		DWORD Pos;
		int m,s,f;
		MCI_PLAY_PARMS pp;
		Pos=MCI_MAKE_TMSF(track,minute,second,frame);
		pp.dwFrom=Pos;
		GetCDTrackLength(track,m,s,f);
		pp.dwTo=MCI_MAKE_TMSF(track,m,s,f);
		pp.dwCallback=(DWORD)m_pWnd->m_hWnd;
		re=mciSendCommand(m_DvcID,
						  MCI_PLAY,MCI_FROM|MCI_TO|MCI_NOTIFY,
					      (DWORD)(LPVOID)&pp
					     );
		if(re)
		{
			throw new CAudioException(re);
			return FALSE;
		}
		//恢复时间格式:
		if(oldtf!=MCI_FORMAT_TMSF)
		{
			SetTimeFormat(oldtf);
		}
	}
	else
	{
		AfxMessageBox("该函数仅供播放CD用!");
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::Pause()
{
	unsigned long re;
	MCI_PLAY_PARMS pp;
	re=mciSendCommand (m_DvcID, MCI_PAUSE, MCI_WAIT, 
	(DWORD)(LPVOID) &pp);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}


BOOL CAudio::Resume()
{
	unsigned long re;
	MCI_PLAY_PARMS pp;
	re=mciSendCommand (m_DvcID, MCI_RESUME, 0, 
	(DWORD)(LPVOID) &pp);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::Stop()
{
	unsigned long re;
	re=mciSendCommand (m_DvcID, MCI_STOP, MCI_WAIT, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::Seek(int min,int sec)
{
	unsigned long re;
	if(m_PlayType==_PLAYMIDI||m_PlayType==_PLAYWAV)
	{
		MCI_SEEK_PARMS SeekParms;
		SeekParms.dwTo = (min*60+sec)*1000;//时间单位为毫秒;
		re=mciSendCommand (m_DvcID, MCI_SEEK, MCI_TO|MCI_WAIT,
			            (DWORD)(LPVOID) 
						&SeekParms);
	}
	else
	{
		AfxMessageBox("该函数只供播放MIDI和Wave文件用!");
	}
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::CDSeek(int track,int minute,int sec,int frame)
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("该函数只供播放CD音轨用!");
		return FALSE;
	}
	int re;
	DWORD Pos;
	Pos=MCI_MAKE_TMSF(track,minute,sec,frame);
	MCI_SEEK_PARMS sp;
	sp.dwTo=Pos;
	re=mciSendCommand (m_DvcID, MCI_SEEK, MCI_TO|MCI_WAIT,
		               (DWORD)(LPVOID) 
					    &sp);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::SeekFirst()
{
	unsigned long re;
	//跳到文件头:
	re=mciSendCommand(m_DvcID, MCI_SEEK,
				   MCI_SEEK_TO_START, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

BOOL CAudio::SeekLast()
{
	unsigned long re;
	//跳到文件尾:
	re=mciSendCommand(m_DvcID, MCI_SEEK,
				   MCI_SEEK_TO_END, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//获取信息:
unsigned long CAudio::GetStatus(DWORD item,DWORD track)
{
	unsigned long re;
	unsigned long flag;
	MCI_STATUS_PARMS sp;
	flag=MCI_STATUS_ITEM|MCI_WAIT;
	sp.dwItem=item;
	if(track!=0)
	{
		sp.dwTrack=track;
		flag|=MCI_TRACK;
	}
	re=mciSendCommand (m_DvcID, MCI_STATUS,flag,
					(DWORD)(LPVOID) &sp);
	if(re)
	{
		throw new CAudioException(re);
		return 0;
	}
	return sp.dwReturn;
}

BOOL CAudio::GetPosition(int & minute,int & second)
{
	if(m_PlayType!=_PLAYMIDI&&m_PlayType!=_PLAYWAV)
	{
		AfxMessageBox("函数GetPosition仅用于播放MIDI和Wave!");
		return FALSE;
	}
	//获取旧的时间格式:
	DWORD oldtf;
	oldtf=GetTimeFormat();
	//设置时间格式:
	unsigned long re;
	MCI_SET_PARMS sp;
	sp.dwTimeFormat=MCI_FORMAT_MILLISECONDS;
	re=mciSendCommand (m_DvcID,MCI_SET,
		               MCI_SET_TIME_FORMAT|MCI_WAIT,
		               (DWORD)(LPVOID) &sp);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	//获取现在的位置:
	DWORD pos;
	pos=GetStatus(MCI_STATUS_POSITION);
	second=(pos/1000)%60;
	minute=(pos/1000-second)/60;
	//恢复原来的时间格式:
	if(oldtf!=MCI_FORMAT_MILLISECONDS)
	{
		SetTimeFormat(oldtf);
	}
	return TRUE;
}

BOOL CAudio::GetCDPosition(int &tracks, int & minutes, int & seconds,int & frames)
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("函数GetCDPosition仅用于播放CD!");
		return FALSE;
	}
	//获取旧的时间格式:
	DWORD oldtf;
	oldtf=GetTimeFormat();
	//设置时间格式:
	SetTimeFormat(MCI_FORMAT_TMSF);
	//获取现在的位置:
	DWORD pos;
	pos=GetStatus(MCI_STATUS_POSITION);
	tracks=MCI_TMSF_TRACK(pos);
	minutes=MCI_TMSF_MINUTE(pos);
	seconds=MCI_TMSF_SECOND(pos);
	frames=MCI_TMSF_FRAME(pos);
	//恢复原来的时间格式:
	if(oldtf!=MCI_FORMAT_TMSF)
	{
		SetTimeFormat(oldtf);
	}
	return TRUE;
}

//录音:
BOOL CAudio::Record()
{
	unsigned long re;
	MCI_RECORD_PARMS RecordParms;
	re=mciSendCommand (m_DvcID, MCI_RECORD, 
					NULL, (DWORD)(LPVOID) 
					&RecordParms);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//保存录制的Wvae文件:
BOOL CAudio::Save(LPCTSTR fn)
{
	unsigned long re;
	MCI_SAVE_PARMS SaveParms;
	SaveParms.lpfilename=fn;
	re=mciSendCommand (m_DvcID, MCI_SAVE,
					   MCI_SAVE_FILE | MCI_WAIT, 
					   (DWORD)(LPVOID) &SaveParms);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//打开CD门:
BOOL CAudio::OpenCDDoor()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("OpenCDDoor()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=mciSendCommand (m_DvcID, MCI_SET,
					   MCI_SET_DOOR_OPEN, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//关上CD门:
BOOL CAudio::CloseCDDoor()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("CloseCDDoor()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=mciSendCommand (m_DvcID, MCI_SET,
					   MCI_SET_DOOR_CLOSED, NULL);
	if(re)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

//读取当前CD音轨:
unsigned long CAudio::GetCDCurTrack()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetCDCurTrack()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_STATUS_CURRENT_TRACK);
	return re;
}

//读取CD状态:
unsigned long CAudio::GetCDMode()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetCDMode()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_STATUS_MODE);
	return re;
}

//读取CD中曲目数目:
unsigned long CAudio::GetCDNumOfSongs()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetCDNumOfSongs()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_STATUS_NUMBER_OF_TRACKS);
	return re;
}

//确定CD是否准备好:
unsigned long CAudio::GetCDReady()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetCDReady()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_STATUS_READY);
	return re;
}

//获取CD音轨的长度:
BOOL CAudio::GetCDTrackLength(int track,int & minutes,int & seconds,int & frames)
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("函数GetCDTrackLength仅供播放CD用");
		return FALSE;
	}
	DWORD len;
	len=GetStatus(MCI_STATUS_LENGTH,track);
	minutes=MCI_MSF_MINUTE(len);
	seconds=MCI_MSF_SECOND(len);
	frames=MCI_MSF_FRAME(len);
	return TRUE;
}

void CAudio::GetLength(int & minutes,int & seconds)
{
	DWORD len;
	DWORD oldtf;
	oldtf=GetTimeFormat();
	if(oldtf!=MCI_FORMAT_MILLISECONDS)
	{
		SetTimeFormat(MCI_FORMAT_MILLISECONDS);
	}
	len=GetStatus(MCI_STATUS_LENGTH);
	seconds=(len/1000)%60;
	minutes=(len/1000-seconds)/60;
	if(oldtf!=MCI_FORMAT_MILLISECONDS)
	{
		SetTimeFormat(oldtf);
	}
}

//确定CD是否在光驱中:
unsigned long CAudio::GetCDInDrive()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetCDInDrive()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_STATUS_MEDIA_PRESENT);
	return re;
}


//检查指定曲目是否为音频曲目:
unsigned long CAudio::GetStatusTypeTrack()
{
	if(m_PlayType!=_PLAYCD)
	{
		AfxMessageBox("GetStatusTypeTrack()函数只能供播放CD用!");
		return FALSE;
	}
	unsigned long re;
	re=GetStatus(MCI_CDA_STATUS_TYPE_TRACK);
	return re;
}

BOOL CAudio::SetTimeFormat(DWORD tfmt)
{
	int re;
	MCI_SET_PARMS setpara;
	
	setpara.dwTimeFormat = tfmt;

	re=mciSendCommand(m_DvcID,MCI_SET, 
        	          MCI_SET_TIME_FORMAT,
					  (DWORD)(LPVOID) &setpara);
	if(re!=0)
	{
		throw new CAudioException(re);
		return FALSE;
	}
	return TRUE;
}

DWORD CAudio::GetTimeFormat()
{
	DWORD tf;
	tf=GetStatus(MCI_STATUS_TIME_FORMAT);
	return tf;
}

//////////////////////////////////////////////////////////////////////
// CAudioException Class
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CAudioException::CAudioException(int re)
{
	m_ErrorNumber=re;
	m_ErrorInfo=new char [255];
}

CAudioException::~CAudioException()
{
	if(m_ErrorInfo)
	{
		delete [] m_ErrorInfo;
	}
}

int CAudioException::GetErrorNumber()
{
	return m_ErrorNumber;
}

LPCTSTR CAudioException::GetErrorMessage()
{
	BOOL re;
	re=mciGetErrorString(m_ErrorNumber,m_ErrorInfo,255);
	if(re==FALSE)
	{
		m_ErrorInfo="获取错误信息失败!";
	}
	return m_ErrorInfo;
}

//////////////////////////////////////////////////////////
//                           EOF                        //
//////////////////////////////////////////////////////////
//前进:
void CAudio::Forward(int sec)
{
	int lt,curp;
	int t,m,s,f;
	if(m_PlayType!=_PLAYCD)
	{
		GetLength(m,s);
		lt=m*60+s;
		GetPosition(m,s);
		curp=m*60+s;
		if((lt-curp)<=sec)
		{
			sec=lt-curp;
		}
		Play(m,s+sec);
	}
	else
	{
		t=GetCDCurTrack();
		GetCDTrackLength(t,m,s,f);
		lt=m*60+s;
		GetCDPosition(t,m,s,f);
		curp=m*60+s;
		if((lt-curp)<=sec)
		{
			sec=lt-curp-1;
		}
		PlayCD(t,m,s+sec);
	}
}
//后退:
void CAudio::Rewind(int sec)
{
	int curp;
	int t,m,s,f;
	if(m_PlayType!=_PLAYCD)
	{
		GetPosition(m,s);
		curp=m*60+s;
		if((curp-sec)<=0)
		{
			Play(0,0);
		}
		else
		{
			Play(m,s-sec);
		}
	}
	else
	{
		GetCDPosition(t,m,s,f);
		curp=m*60+s;
		if((curp-sec)<=0)
		{
			PlayCD(t,0,0);
		}
		else
		{
			PlayCD(t,m,s-sec);
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -