【VC开源代码栏目提醒】:网学会员为需要VC开源代码的朋友们搜集整理了MIDI.CPP相关资料,希望对各位网友有所帮助!
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998 by J鰎g K鰊ig
// All rights reserved
//
// This file is part of the completely free tetris clone "CGTetris".
//
// This is free software.
// You may redistribute it by any means providing it is not sold for profit
// without the authors written consent.
//
// No warrantee of any kind, expressed or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// Send bug reports, bug fixes, enhancements, requests, flames, etc., and
// I'll try to keep a version up to date. I can be reached as follows:
// J.Koenig@adg.de (company site)
// Joerg.Koenig@rhein-neckar.de (private site)
/////////////////////////////////////////////////////////////////////////////
// Midi.cpp
//
// The CMIDI class is based on a sample in the DirectX SDK (mstream)
#include "stdafx.h"
#include "Midi.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MThd 0x6468544D // Start of file
#define MTrk 0x6B72544D // Start of track
#define BUFFER_TIME_LENGTH 60 // Amount to fill in milliseconds
// These structures are stored in MIDI files; they need to be byte aligned.
//
#pragma pack(1)
// Contents of MThd chunk.
struct MIDIFILEHDR
{
WORD wFormat; // Format (hi-lo)
WORD wTrackCount; // # tracks (hi-lo)
WORD wTimeDivision; // Time division (hi-lo)
};
#pragma pack() // End of need for byte-aligned structures
// Macros for swapping hi/lo-endian data
//
#define WORDSWAP(w) (((w) >> 8) | \
(((w) << 8) & 0xFF00))
#define DWORDSWAP(dw) (((dw) >> 24) | \
(((dw) >> 8) & 0x0000FF00) | \
(((dw) << 8) & 0x00FF0000) | \
(((dw) << 24) & 0xFF000000))
static char gteBadRunStat[] = "Reference to
missing running status.";
static char gteRunStatMsgTrunc[]= "Running status message truncated";
static char gteChanMsgTrunc[] = "Channel message truncated";
static char gteSysExLenTrunc[] = "SysEx event truncated (length)";
static char gteSysExTrunc[] = "SysEx event truncated";
static char gteMetaNoClass[] = "Meta event truncated (no class byte)";
static char gteMetaLenTrunc[] = "Meta event truncated (length)";
static char gteMetaTrunc[] = "Meta event truncated";
static char gteNoMem[] = "Out of memory during malloc call";
//////////////////////////////////////////////////////////////////////
// CMIDI -- Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMIDI::CMIDI()
: m_dwSoundSize(0)
, m_pSoundData(0)
, m_dwFormat(0)
, m_dwTrackCount(0)
, m_dwTimeDivision(0)
, m_bPlaying(FALSE)
, m_hStream(0)
, m_dwProgressBytes(0)
, m_bLooped(FALSE)
, m_tkCurrentTime(0)
, m_dwBufferTickLength(0)
, m_dwCurrentTempo(0)
, m_dwTempoMultiplier(100)
, m_bInsertTempo(FALSE)
, m_bBuffersPrepared(FALSE)
, m_nCurrentBuffer(0)
, m_uMIDIDeviceID(MIDI_MAPPER)
, m_nEmptyBuffers(0)
, m_bPaused(FALSE)
, m_uCallbackStatus(0)
, m_hBufferReturnEvent(0)
, m_ptsTrack(0)
, m_ptsFound(0)
, m_dwStatus(0)
, m_tkNext(0)
, m_dwMallocBlocks(0)
{
m_hBufferReturnEvent = ::CreateEvent(0, FALSE, FALSE, TEXT("Wait For Buffer Return"));
ASSERT(m_hBufferReturnEvent != 0);
}
CMIDI::~CMIDI()
{
Stop(FALSE);
if(m_hBufferReturnEvent)
::CloseHandle(m_hBufferReturnEvent);
}
BOOL CMIDI::Create(UINT uResID, CWnd * pWndParent /* = NULL */)
{
return Create(MAKEINTRESOURCE(uResID), pWndParent);
}
BOOL CMIDI::Create(LPCTSTR pszResID, CWnd * pWndParent /* = NULL */)
{
//////////////////////////////////////////////////////////////////
// load resource
HINSTANCE hApp = ::GetModuleHandle(0);
ASSERT(hApp);
HRSRC hResInfo = ::FindResource(hApp, pszResID, TEXT("MIDI"));
if(hResInfo == 0)
return FALSE;
HGLOBAL hRes = ::LoadResource(hApp, hResInfo);
if(hRes == 0)
return FALSE;
LPVOID pTheSound = ::LockResource(hRes);
if(pTheSound == 0)
return FALSE;
DWORD dwTheSound = ::SizeofResource(hApp, hResInfo);
return Create(pTheSound, dwTheSound, pWndParent);
}
BOOL CMIDI::Create(LPVOID pSoundData, DWORD dwSize, CWnd * pWndParent /* = NULL */)
{
if( m_pSoundData ) {
// already created
ASSERT(FALSE);
return FALSE;
}
ASSERT(pSoundData != 0);
ASSERT(dwSize > 0);
regis