请问高手,CMidiStream这个类是做什么用的,我在看一个BSP里有这个类,不知道做什么用的,谢谢!
嘿嘿,你可以查帮助文档哦,那里面提供的远比我们能给你提供的详细。CMidiStream是自定义的吧,由第三方提供的,我在帮助文档中没有搜到。
建议:贴代码吧,让这里的大侠帮你分析分析,我小菜凑个热闹,嘿嘿。
谢谢解答!有点看明白了,下面是源代码:
#include "wavemain.h"
void CMidiStream::GainChange()
{
PLIST_ENTRY pListEntry;
CMidiNote *pCNote;
pListEntry = m_NoteList.Flink;
while (pListEntry != &m_NoteList)
{
// Get a pointer to the stream context
pCNote = CONTAINING_RECORD(pListEntry,CMidiNote,m_Link);
pCNote->GainChange();
pListEntry = pListEntry->Flink;
}
}
DWORD CMidiStream::MapNoteGain(DWORD NoteGain)
{
NoteGain *= m_dwGain; // Calc. aggregate gain
NoteGain += 0xFFFF; // Force to round up
NoteGain >>= 16;
return MapGain(NoteGain);
}
HRESULT CMidiStream::Open(DeviceContext *pDeviceContext, LPWAVEOPENDESC lpWOD, DWORD dwFlags)
{
HRESULT Result;
LPWAVEFORMAT_MIDI pwfxmidi = (LPWAVEFORMAT_MIDI) lpWOD->lpFormat;
if (pwfxmidi->wfx.cbSize!=WAVEFORMAT_MIDI_EXTRASIZE)
{
return E_FAIL;
}
m_USecPerQuarterNote = pwfxmidi->USecPerQuarterNote;
m_TicksPerQuarterNote = pwfxmidi->TicksPerQuarterNote;
UpdateTempo();
m_DeltaSampleCount=0;
// Add all notes to free list
InitializeListHead(&m_NoteList);
InitializeListHead(&m_FreeList);
for (int i=0;i
{
InsertTailList(&m_FreeList,&m_MidiNote.m_Link);
}
Result = StreamContext::Open(pDeviceContext, lpWOD, dwFlags);
return Result;
}
DWORD CMidiStream::Reset()
{
DWORD dwResult = StreamContext::Reset();
if (dwResult==MMSYSERR_NOERROR)
{
AllNotesOff(0);
}
return dwResult;
}
DWORD CMidiStream::Close()
{
DWORD dwResult = StreamContext::Close();
if (dwResult==MMSYSERR_NOERROR)
{
AllNotesOff(0);
}
return dwResult;
}
HRESULT CMidiStream::UpdateTempo()
{
if (m_USecPerQuarterNote==0)
{
m_USecPerQuarterNote = 500000; // If not specified, assume 500000usec = 1/2 sec per quarter note
}
if (m_TicksPerQuarterNote==0)
{
m_TicksPerQuarterNote = 96; // If not specified, assume 96 ticks/quarter note
}
UINT64 Num = SAMPLERATE;
Num *= m_USecPerQuarterNote;
UINT64 Den = 1000000;
Den *= m_TicksPerQuarterNote;
UINT64 SamplesPerTick = Num/Den;
m_SamplesPerTick = (UINT32)SamplesPerTick;
return S_OK;
}
// Return the delta # of samples until the next midi event
// or 0 if no midi events are left in the queue
UINT32 CMidiStream::ProcessMidiStream()
{
WAVEFORMAT_MIDI_MESSAGE *pMsg;
WAVEFORMAT_MIDI_MESSAGE *pMsgEnd;
UINT32 ThisMidiEventDelta;
// Process all midi messages up to and including the current sample
pMsg = (WAVEFORMAT_MIDI_MESSAGE *)m_lpCurrData;
pMsgEnd = (WAVEFORMAT_MIDI_MESSAGE *)m_lpCurrDataEnd;
for (;;)
{
if (pMsg>=pMsgEnd)
{
pMsg = (WAVEFORMAT_MIDI_MESSAGE *)GetNextBuffer();
if (!pMsg)
{
// DEBUGMSG(1, (TEXT("CMidiStream::ProcessMidiStream no more events\r\n")));
return 0;
}
pMsgEnd = (WAVEFORMAT_MIDI_MESSAGE *)m_lpCurrDataEnd;
}
ThisMidiEventDelta = DeltaTicksToSamples(pMsg->DeltaTicks);
if (ThisMidiEventDelta > m_DeltaSampleCount)
{
m_lpCurrData = (PBYTE)pMsg;
INT32 Delta = ThisMidiEventDelta-m_DeltaSampleCount;
// DEBUGMSG(1, (TEXT("CMidiStream::ProcessMidiStream next event @delta %d\r\n"),Delta));
return Delta;
}
// DEBUGMSG(1, (TEXT("CMidiStream::ProcessMidiStream sending midi message 0x%x\r\n"),pMsg->MidiMsg));
InternalMidiMessage(pMsg->MidiMsg);
m_DeltaSampleCount=0;
pMsg++;
}
}