PersonalCorpus 版 (精华区)

多媒体程序设计
播放MIDI音频 hjt整理
class CMidi
{
public:
    CMidi();//构造函数
    virtual ~CMidi();//构析函数
    int GetDevices (void);//获得播放设备
    BOOL Open (CString);//打开MIDI文件
    void Close (void);//关闭MIDI文件
    BOOL Play (void);//播放MIDI文件
    void Stop (void);//停止播放MIDI文件
    void Pause (void);//暂停播放MIDI文件
    //函数功能-获得MIDI乐曲长度,*pnMinutes,*pnSeconds将会返         
    //回MIDI的分钟和秒钟
    void GetMidiLength (int *pnMinutes, int *pnSeconds);    
    int GetMinutes (void);//获得当前播放的分钟数
    int GetSeconds (void);//获得当前播放的秒钟数
    BOOL IsPlaying (BOOL *);//是否正在播放
    //函数功能-跳到某位置,nMinutes,nSeconds-MIDI将要跳到的MIDI乐       
    //曲的位置
    BOOL SeekTo (int, int);
    void Forward (int);//快进
    void Backward (int);//后退
    int GetTempo (void);//获得节拍
    void SetTempo (int);//设置节拍
    
private:
    BOOL m_bOpened;//是否打开MIDI文件
    BOOL m_bPaused;//是否暂停
    BOOL m_bPlaying;//是否正在播放
    WORD m_wDeviceID;//播放设备ID
};

//函数实现
CMidi::CMidi()
{
    // 初始化成员变量
    m_bOpened  =  FALSE;
    m_bPaused  =  FALSE;
    m_bPlaying =  FALSE;
    m_wDeviceID = 0;
}

CMidi::~CMidi()
{
    Close ();
}

//得到设备ID
int CMidi::GetDevices (void)
{
    return (int) midiOutGetNumDevs ();
}

//打开文件
BOOL CMidi::Open (CString Filename)
{
    if (!m_bOpened)
    {
        // 初始化成员变量
        m_bOpened = m_bPaused = m_bPlaying = FALSE;
        m_wDeviceID = 0;
        // 文件是否存在
        CFileStatus Status;
        if (!CFile::GetStatus (Filename, Status))
            return FALSE;
        // 打开设备
        MCI_OPEN_PARMS OpenParms;
        OpenParms.lpstrDeviceType =
             (LPCSTR) MCI_DEVTYPE_SEQUENCER;
        OpenParms.lpstrElementName = (LPCSTR) Filename;
        OpenParms.wDeviceID = 0;
        if (mciSendCommand (NULL, MCI_OPEN, MCI_WAIT |                  
            MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT,
            (DWORD)(LPVOID) &OpenParms))
            return FALSE;
        m_wDeviceID = OpenParms.wDeviceID;
        m_bOpened = TRUE;
        // 将时间格式设为毫秒
        MCI_SET_PARMS SetParms;
        SetParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
        if (mciSendCommand (m_wDeviceID, MCI_SET,                   
            MCI_SET_TIME_FORMAT,
            (DWORD)(LPVOID) &SetParms))
        {
            Close ();
            return FALSE;
        }
        mciSendCommand (m_wDeviceID, MCI_SEEK,     
            MCI_SEEK_TO_START, NULL);
    }
    return TRUE;
}

//关闭正在播放的文件
void CMidi::Close (void)
{
    if (m_bOpened)
    {
        // 停止播放关闭设备
        if (m_bPlaying || m_bPaused)
            mciSendCommand (m_wDeviceID, MCI_STOP, NULL,                
                NULL);
        mciSendCommand (m_wDeviceID, MCI_CLOSE, NULL, NULL);
        // 成员变量复位
        m_bOpened = m_bPaused = m_bPlaying = FALSE;
        m_wDeviceID = 0;
    }
}

//播放
BOOL CMidi::Play (void)
{
    if (m_bOpened)
    {
        MCI_PLAY_PARMS PlayParms;
        PlayParms.dwCallback = NULL;
        PlayParms.dwFrom = ((GetMinutes () * 60) +
            GetSeconds()) * 1000;
        if (mciSendCommand (m_wDeviceID, MCI_PLAY, MCI_FROM,            
            (DWORD)(LPVOID) &PlayParms))
            return FALSE;
        m_bPaused = FALSE;
        m_bPlaying = TRUE;
        return TRUE;
    }
    return FALSE;
}

//停止播放
void CMidi::Stop (void)
{
    if (m_bOpened && m_bPlaying)
    {
        //停止
        mciSendCommand (m_wDeviceID, MCI_STOP, NULL, NULL);
        //复位
        mciSendCommand (m_wDeviceID, MCI_SEEK,          
            MCI_SEEK_TO_START, NULL);
        m_bPlaying = FALSE;
        m_bPaused = FALSE;
    }
}

//暂停播放
void CMidi::Pause( void )
{
    if (m_bOpened && m_bPlaying)
    {
        MCI_PLAY_PARMS PlayParms;
        if (mciSendCommand (m_wDeviceID, MCI_PAUSE, 0,          
            (DWORD)(LPVOID) &PlayParms))
            return;
        m_bPaused = TRUE;
    }
}

//获得MIDI乐曲长度
void CMidi::GetMidiLength (int *pnMinutes, int *pnSeconds)
{
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        StatusParms.dwItem = MCI_STATUS_LENGTH;
        if (mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms))
        {
            *pnMinutes = -1;
            *pnSeconds = -1;
            return;
        }
        *pnMinutes = (StatusParms.dwReturn / 1000) / 60;
        *pnSeconds = (StatusParms.dwReturn / 1000) % 60;
        return;
    }
    *pnMinutes = -1;
    *pnSeconds = -1;
}

//获得当前播放的分钟数
int CMidi::GetMinutes (void)
{
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        StatusParms.dwItem = MCI_STATUS_POSITION;
        if (mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms))
            return -1;
        return (int) ((StatusParms.dwReturn / 1000) / 60);
    }
    return -1;
}
//获得当前播放的秒钟数
int CMidi::GetSeconds (void)
{
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        StatusParms.dwItem = MCI_STATUS_POSITION;
        if (mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms))
            return -1;
        return (int) ((StatusParms.dwReturn / 1000) % 60);
    }
    return -1;
}
//是否正在播放
BOOL CMidi::IsPlaying (BOOL *pbPaused)
{
    *pbPaused = m_bPaused;
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        StatusParms.dwItem = MCI_STATUS_MODE;
        if (mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms))
            return FALSE;
        if (StatusParms.dwReturn == MCI_MODE_PLAY)
        {
            m_bPlaying = TRUE;
            m_bPaused = FALSE;
            return TRUE;
        }
        else if (StatusParms.dwReturn == MCI_MODE_PAUSE)
        {
            m_bPlaying = TRUE;
            m_bPaused = FALSE;
            return TRUE;
        }
        else
        {
            m_bPlaying = FALSE;
            m_bPaused = FALSE;
            return FALSE;
        }
    }
    return FALSE;
}
BOOL CMidi::SeekTo (int nMinute, int nSecond)
{
    if (m_bOpened)
    {
        MCI_SEEK_PARMS SeekParms;
        SeekParms.dwTo = (nMinute * 60 + nSecond) * 1000;
        if (m_bPlaying && !m_bPaused)
            mciSendCommand (m_wDeviceID, MCI_PAUSE, 0,                  
                NULL);
        if (mciSendCommand (m_wDeviceID, MCI_SEEK,
            MCI_TO | MCI_WAIT,
            (DWORD)(LPVOID) &SeekParms))
            return FALSE;
        if (m_bPlaying && !m_bPaused)
            Play ();
        return TRUE;
    }
    return FALSE;
}

//快进
void CMidi::Forward (int nSeconds)
{
    if (m_bOpened)
    {
        // 得到当前位置
        MCI_STATUS_PARMS StatusParms;
        DWORD dwPos;
        StatusParms.dwItem = MCI_STATUS_POSITION;
        mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms);
        dwPos = StatusParms.dwReturn;
        // 将当前位置增加
        dwPos += (DWORD) nSeconds * 1000;
        // 停止并寻找位置
        MCI_SEEK_PARMS SeekParms;
        SeekParms.dwTo = dwPos;
        if (m_bPlaying && !m_bPaused)
            mciSendCommand (m_wDeviceID, MCI_PAUSE, 0,              
                NULL);
        mciSendCommand (m_wDeviceID, MCI_SEEK,
            MCI_TO | MCI_WAIT,
            (DWORD)(LPVOID) &SeekParms);
        // 恢复播放
        if (m_bPlaying && !m_bPaused)
            Play ();
        }
}
//后退
void CMidi::Backward (int nSeconds)
{
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        DWORD dwPos;
        StatusParms.dwItem = MCI_STATUS_POSITION;
        mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms);
        dwPos = StatusParms.dwReturn;
        dwPos -= (DWORD) nSeconds * 1000;
        MCI_SEEK_PARMS SeekParms;
        SeekParms.dwTo = dwPos;
        if (m_bPlaying && !m_bPaused)
            mciSendCommand (m_wDeviceID, MCI_PAUSE, 0, NULL);
        mciSendCommand (m_wDeviceID, MCI_SEEK,
            MCI_TO | MCI_WAIT,
            (DWORD)(LPVOID) &SeekParms);
        if (m_bPlaying && !m_bPaused)
            Play ();
    }
}
//获得节拍
int CMidi::GetTempo (void)
{
    if (m_bOpened)
    {
        MCI_STATUS_PARMS StatusParms;
        StatusParms.dwItem = MCI_SEQ_STATUS_TEMPO;
        if (mciSendCommand (m_wDeviceID, MCI_STATUS,
            MCI_WAIT | MCI_STATUS_ITEM,
            (DWORD)(LPVOID) &StatusParms))
            return -1;
        return (int) StatusParms.dwReturn;  
    }
    return -1;
}
//设置节拍
void CMidi::SetTempo (int nTempo)
{
    if (m_bOpened)
    {
        MCI_SEQ_SET_PARMS SeqSetParms;
        SeqSetParms.dwTempo = nTempo;
        mciSendCommand (m_wDeviceID, MCI_SET,
            MCI_WAIT | MCI_SEQ_SET_TEMPO,
            (DWORD)(LPVOID) &SeqSetParms);
    }
}
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:213.897毫秒