亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? midi.cpp

?? "幸運52"游戲 拼圖游戲 游戲歌曲實力大比拼 貪食蛇 俄羅斯方塊 網絡五子棋 源碼
?? CPP
?? 第 1 頁 / 共 3 頁
字號:
		} else
			lpciInfo->bTimesUp = TRUE;

	DWORD tkNow = m_tkCurrentTime;

	// Delta time is absolute event time minus absolute time
	// already gone by on this track
	DWORD tkDelta = pteTemp->tkEvent - m_tkCurrentTime;

	// Event time is now current time on this track
	m_tkCurrentTime = pteTemp->tkEvent;

	if( m_bInsertTempo ) {
		m_bInsertTempo = FALSE;

		if( lpciInfo->dwMaxLength-lpciInfo->dwBytesRecorded < 3*sizeof(DWORD)) {
			// Cleanup from our write operation
			return CONVERTERR_BUFFERFULL;
		}
		if( m_dwCurrentTempo ) {
			pmeEvent->dwDeltaTime = 0;
			pmeEvent->dwStreamID = 0;
			pmeEvent->dwEvent = ( m_dwCurrentTempo * 100 ) / m_dwTempoMultiplier;
			pmeEvent->dwEvent |= (((DWORD)MEVT_TEMPO ) << 24 ) | MEVT_F_SHORT;

			lpciInfo->dwBytesRecorded += 3 * sizeof(DWORD);
			pmeEvent += 3 * sizeof(DWORD);
		}
	}

	if( pteTemp->byShortData[0] < MIDI_SYSEX ) {
		// Channel message. We know how long it is, just copy it.
		// Need 3 DWORD's: delta-t, stream-ID, event
		if( lpciInfo->dwMaxLength-lpciInfo->dwBytesRecorded < 3*sizeof(DWORD)) {
			// Cleanup from our write operation
			return CONVERTERR_BUFFERFULL;
		}

		pmeEvent->dwDeltaTime = tkDelta;
		pmeEvent->dwStreamID = 0;
		pmeEvent->dwEvent = ( pteTemp->byShortData[0] )
					| (((DWORD)pteTemp->byShortData[1] ) << 8 )
					| (((DWORD)pteTemp->byShortData[2] ) << 16 )
					| MEVT_F_SHORT;

		if((( pteTemp->byShortData[0] & 0xF0) == MIDI_CTRLCHANGE ) && ( pteTemp->byShortData[1] == MIDICTRL_VOLUME )) {
			// If this is a volume change, generate a callback so we can grab
			// the new volume for our cache
			pmeEvent->dwEvent |= MEVT_F_CALLBACK;
		}
		lpciInfo->dwBytesRecorded += 3 *sizeof(DWORD);
	} else if(( pteTemp->byShortData[0] == MIDI_SYSEX ) || ( pteTemp->byShortData[0] == MIDI_SYSEXEND )) {
		TRACE0("AddEventToStreamBuffer: Ignoring SysEx event.\n");
		if( m_dwMallocBlocks ) {
			delete [] pteTemp->pLongData;
			--m_dwMallocBlocks;
		}
	} else {
		// Better be a meta event.
		//  BYTE	byEvent
		//  BYTE	byEventType
		//  VDWORD	dwEventLength
		//  BYTE	pLongEventData[dwEventLength]
		ASSERT( pteTemp->byShortData[0] == MIDI_META );

		// The only meta-event we care about is change tempo
		if( pteTemp->byShortData[1] != MIDI_META_TEMPO ) {
			if( m_dwMallocBlocks ) {
				delete [] pteTemp->pLongData;
				--m_dwMallocBlocks;
			}
			return CONVERTERR_METASKIP;
		}

		// We should have three bytes of parameter data...
		ASSERT(pteTemp->dwEventLength == 3);

		// Need 3 DWORD's: delta-t, stream-ID, event data
		if( lpciInfo->dwMaxLength - lpciInfo->dwBytesRecorded < 3 *sizeof(DWORD)) {
			// Cleanup the temporary event if necessary and return
			if( m_dwMallocBlocks ) {
				delete [] pteTemp->pLongData;
				--m_dwMallocBlocks;
			}
			return CONVERTERR_BUFFERFULL;
		}

		pmeEvent->dwDeltaTime = tkDelta;
		pmeEvent->dwStreamID = 0;
	// Note: this is backwards from above because we're converting a single
	//		 data value from hi-lo to lo-hi format...
		pmeEvent->dwEvent = ( pteTemp->pLongData[2] )
				| (((DWORD)pteTemp->pLongData[1] ) << 8 )
				| (((DWORD)pteTemp->pLongData[0] ) << 16 );

		// This next step has absolutely nothing to do with the conversion of a
		// MIDI file to a stream, it's simply put here to add the functionality
		// of the tempo slider. If you don't need this, be sure to remove the
		// next two lines.
		m_dwCurrentTempo = pmeEvent->dwEvent;
		pmeEvent->dwEvent = (pmeEvent->dwEvent * 100 ) / m_dwTempoMultiplier;

		pmeEvent->dwEvent |= (((DWORD)MEVT_TEMPO ) << 24 ) | MEVT_F_SHORT;

		m_dwBufferTickLength = (m_dwTimeDivision * 1000 * BUFFER_TIME_LENGTH) / m_dwCurrentTempo;
		TRACE1("m_dwBufferTickLength = %lu\n", m_dwBufferTickLength);

		if( m_dwMallocBlocks ) {
			delete [] pteTemp->pLongData;
			--m_dwMallocBlocks;
		}
		lpciInfo->dwBytesRecorded += 3 *sizeof(DWORD);
	}

	return CONVERTERR_NOERROR;
}


// StreamBufferSetup()
//
// Opens a MIDI stream. Then it goes about converting the data into a midiStream buffer for playback.
BOOL CMIDI :: StreamBufferSetup() {
	int		nChkErr;
	BOOL	bFoundEnd = FALSE;

	MMRESULT		mmrRetVal;

	if( !m_hStream )
		if(( mmrRetVal = midiStreamOpen( &m_hStream,
					&m_uMIDIDeviceID,
					DWORD(1), DWORD(MidiProc),
					DWORD(this),
					CALLBACK_FUNCTION )) != MMSYSERR_NOERROR ) {
		MidiError(mmrRetVal);
		return FALSE;
	}

	// allocate stream buffers and initialise them
	m_StreamBuffers.resize(NUM_STREAM_BUFFERS);

	MIDIPROPTIMEDIV mptd;
	mptd.cbStruct = sizeof(mptd);
	mptd.dwTimeDiv = m_dwTimeDivision;
	if(( mmrRetVal = midiStreamProperty( m_hStream, (LPBYTE)&mptd,
					    MIDIPROP_SET | MIDIPROP_TIMEDIV )) != MMSYSERR_NOERROR ) {
		MidiError( mmrRetVal );
		return FALSE;
	}

	m_nEmptyBuffers = 0;
	DWORD dwConvertFlag = CONVERTF_RESET;

	for( m_nCurrentBuffer = 0; m_nCurrentBuffer < NUM_STREAM_BUFFERS; m_nCurrentBuffer++ ) {
		m_StreamBuffers[m_nCurrentBuffer].mhBuffer.dwBufferLength = OUT_BUFFER_SIZE;
		m_StreamBuffers[m_nCurrentBuffer].mhBuffer.lpData = new char [OUT_BUFFER_SIZE];
		if( m_StreamBuffers[m_nCurrentBuffer].mhBuffer.lpData == 0 )
			return FALSE;

		// Tell the converter to convert up to one entire buffer's length of output
		// data. Also, set a flag so it knows to reset any saved state variables it
		// may keep from call to call.
		m_StreamBuffers[m_nCurrentBuffer].dwStartOffset = 0;
		m_StreamBuffers[m_nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE;
		m_StreamBuffers[m_nCurrentBuffer].tkStart = 0;
		m_StreamBuffers[m_nCurrentBuffer].bTimesUp = FALSE;

		if(( nChkErr = ConvertToBuffer( dwConvertFlag, &m_StreamBuffers[m_nCurrentBuffer] )) != CONVERTERR_NOERROR ) {
			if( nChkErr == CONVERTERR_DONE ) {
				bFoundEnd = TRUE;
			} else {
				TRACE0("Initial conversion pass failed\n");
				return FALSE;
			}
		}
		m_StreamBuffers[m_nCurrentBuffer].mhBuffer.dwBytesRecorded = m_StreamBuffers[m_nCurrentBuffer].dwBytesRecorded;

		if( !m_bBuffersPrepared )
			if(( mmrRetVal = midiOutPrepareHeader( (HMIDIOUT)m_hStream,
						&m_StreamBuffers[m_nCurrentBuffer].mhBuffer,
						sizeof(MIDIHDR))) != MMSYSERR_NOERROR ) {
				MidiError( mmrRetVal );
				return FALSE;
			}

		if(( mmrRetVal = midiStreamOut( m_hStream,
						&m_StreamBuffers[m_nCurrentBuffer].mhBuffer,
						sizeof(MIDIHDR))) != MMSYSERR_NOERROR ) {
			MidiError(mmrRetVal);
			break;
		}
		dwConvertFlag = 0;

		if( bFoundEnd )
			break;
	}

	m_bBuffersPrepared = TRUE;
	m_nCurrentBuffer = 0;
	return TRUE;
}

// This function unprepares and frees all our buffers -- something we must
// do to work around a bug in MMYSYSTEM that prevents a device from playing
// back properly unless it is closed and reopened after each stop.
void CMIDI :: FreeBuffers() {
	DWORD	idx;
	MMRESULT	mmrRetVal;

	if( m_bBuffersPrepared ) {
		for( idx = 0; idx < NUM_STREAM_BUFFERS; idx++ )
			if(( mmrRetVal = midiOutUnprepareHeader( (HMIDIOUT)m_hStream,
								&m_StreamBuffers[idx].mhBuffer,
								sizeof(MIDIHDR))) != MMSYSERR_NOERROR ) {
				MidiError(mmrRetVal);
			}
		m_bBuffersPrepared = FALSE;
	}
	// Free our stream buffers...
	for( idx = 0; idx < NUM_STREAM_BUFFERS; idx++ )
	if( m_StreamBuffers[idx].mhBuffer.lpData ) {
		delete [] m_StreamBuffers[idx].mhBuffer.lpData;
		m_StreamBuffers[idx].mhBuffer.lpData = 0;
	}
}

//////////////////////////////////////////////////////////////////////
// CMIDI -- error handling
//////////////////////////////////////////////////////////////////////

void CMIDI :: MidiError(MMRESULT mmResult) {
	#ifdef _DEBUG
		char chText[512];
		midiOutGetErrorText(mmResult, chText, sizeof(chText));
		TRACE1("Midi error: %hs\n", chText);
	#endif
}


void CMIDI :: TrackError(TRACK * ptsTrack, LPSTR lpszErr ) {
	TRACE1("Track buffer offset %lu\n", (DWORD)(ptsTrack->pTrackCurrent - ptsTrack->pTrackStart));
    TRACE1("Track total length %lu\n", ptsTrack->dwTrackLength);
	TRACE1("%hs\n", lpszErr);
}

//////////////////////////////////////////////////////////////////////
// CMIDI -- overridables
//////////////////////////////////////////////////////////////////////

void CMIDI :: OnMidiOutOpen() {
}


void CMIDI :: OnMidiOutDone(MIDIHDR & rHdr) {
	if( m_uCallbackStatus == STATUS_CALLBACKDEAD )
		return;

	++m_nEmptyBuffers;

	if( m_uCallbackStatus == STATUS_WAITINGFOREND ) {
		if( m_nEmptyBuffers < NUM_STREAM_BUFFERS )
			return;
		else {
			m_uCallbackStatus = STATUS_CALLBACKDEAD;
			Stop();
			SetEvent(m_hBufferReturnEvent);
			return;
		}
	}

	// This flag is set whenever the callback is waiting for all buffers to
	// come back.
	if( m_uCallbackStatus == STATUS_KILLCALLBACK ) {
		// Count NUM_STREAM_BUFFERS-1 being returned for the last time
		if( m_nEmptyBuffers < NUM_STREAM_BUFFERS )
			return;
		else {
			// Change the status to callback dead
			m_uCallbackStatus = STATUS_CALLBACKDEAD;
			SetEvent(m_hBufferReturnEvent);
			return;
		}
	}

	m_dwProgressBytes += m_StreamBuffers[m_nCurrentBuffer].mhBuffer.dwBytesRecorded;

	///////////////////////////////////////////////////////////////////////////////
	// Fill an available buffer with audio data again...

	if( m_bPlaying && m_nEmptyBuffers ) {
		m_StreamBuffers[m_nCurrentBuffer].dwStartOffset = 0;
		m_StreamBuffers[m_nCurrentBuffer].dwMaxLength = OUT_BUFFER_SIZE;
		m_StreamBuffers[m_nCurrentBuffer].tkStart = 0;
		m_StreamBuffers[m_nCurrentBuffer].dwBytesRecorded = 0;
		m_StreamBuffers[m_nCurrentBuffer].bTimesUp = FALSE;

		int nChkErr;

		if(( nChkErr = ConvertToBuffer( 0, &m_StreamBuffers[m_nCurrentBuffer] )) != CONVERTERR_NOERROR ) {
			if( nChkErr == CONVERTERR_DONE ) {
				m_uCallbackStatus = STATUS_WAITINGFOREND;
				return;
			} else {
				TRACE0("MidiProc() conversion pass failed!\n");
				return;
			}
		}

		m_StreamBuffers[m_nCurrentBuffer].mhBuffer.dwBytesRecorded = m_StreamBuffers[m_nCurrentBuffer].dwBytesRecorded;

		MMRESULT mmrRetVal;
		if( (mmrRetVal = midiStreamOut(m_hStream, &m_StreamBuffers[m_nCurrentBuffer].mhBuffer, sizeof(MIDIHDR))) != MMSYSERR_NOERROR ) {
			MidiError(mmrRetVal);
			return;
		}
		m_nCurrentBuffer = ( m_nCurrentBuffer + 1 ) % NUM_STREAM_BUFFERS;
		m_nEmptyBuffers--;
	}
}


void CMIDI :: OnMidiOutPositionCB(MIDIHDR & rHdr, MIDIEVENT & rEvent) {
	if( MIDIEVENT_TYPE(rEvent.dwEvent) == MIDI_CTRLCHANGE )
	{
		if( MIDIEVENT_DATA1(rEvent.dwEvent) == MIDICTRL_VOLUME ) {
			// Mask off the channel number and cache the volume data byte
			m_Volumes[MIDIEVENT_CHANNEL(rEvent.dwEvent)] = DWORD(MIDIEVENT_VOLUME(rEvent.dwEvent)*100/VOLUME_MAX);
			if( m_pWndParent && ::IsWindow(m_pWndParent->GetSafeHwnd()) )
				// Do not use SendMessage(), because a change of the midi stream has no effect
				// during callback handling, so if the owner wants to adjust the volume, as a
				// result of the windows message, (s)he will not hear that change.
				m_pWndParent->PostMessage(
					WM_MIDI_VOLUMECHANGED,
					WPARAM(this),
					LPARAM(
						MAKELONG(
							WORD(MIDIEVENT_CHANNEL(rEvent.dwEvent)),
							WORD(MIDIEVENT_VOLUME(rEvent.dwEvent)*100/VOLUME_MAX)
						)
					)
				);
		}
	}
}


void CMIDI :: OnMidiOutClose() {
}

//////////////////////////////////////////////////////////////////////
// CMIDI -- static members
//////////////////////////////////////////////////////////////////////

void CMIDI :: MidiProc(HMIDIOUT hMidi, UINT uMsg, DWORD dwInstanceData, DWORD dwParam1, DWORD dwParam2) {
	CMIDI * pMidi = (CMIDI *) dwInstanceData;
	ASSERT(pMidi != 0);
	MIDIHDR * pHdr = (MIDIHDR*) dwParam1;

	switch(uMsg) {
		case MOM_OPEN:
			pMidi->OnMidiOutOpen();
			break;

		case MOM_CLOSE:
			pMidi->OnMidiOutClose();
			break;

		case MOM_DONE:
			ASSERT(pHdr != 0);
			pMidi->OnMidiOutDone(*pHdr);
			break;

		case MOM_POSITIONCB:
			ASSERT(pHdr != 0);
			pMidi->OnMidiOutPositionCB(*pHdr, *((MIDIEVENT*)(pHdr->lpData + pHdr->dwOffset)));
			break;

		default:
			break;
	}
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
在线免费观看日本欧美| 偷拍与自拍一区| 国产精品影视网| 国产婷婷一区二区| 粉嫩av一区二区三区粉嫩| 国产精品黄色在线观看| 一本一道综合狠狠老| 亚洲国产一二三| 欧美一三区三区四区免费在线看| 丝袜美腿成人在线| 久久综合成人精品亚洲另类欧美| 国产福利一区二区三区| 国产精品久久久久久福利一牛影视| 成人动漫一区二区| 亚洲曰韩产成在线| 日韩欧美的一区二区| 国产成人精品亚洲777人妖| 亚洲欧洲精品一区二区精品久久久 | 欧美激情中文不卡| 色婷婷av一区二区三区gif| 午夜一区二区三区视频| 日韩欧美国产1| 99久免费精品视频在线观看| 亚洲成人福利片| 精品国产污污免费网站入口 | 欧美日韩在线免费视频| 久久精品国产亚洲5555| 国产精品色眯眯| 欧美三级视频在线| 国产精品一区二区男女羞羞无遮挡| 国产精品卡一卡二| 欧美日韩国产在线观看| 国产成人av一区二区三区在线 | 中文字幕一区二区三区不卡| 欧美精品精品一区| 成人精品高清在线| 日韩中文字幕亚洲一区二区va在线 | 精品一区二区三区在线播放| 亚洲欧美在线视频| 日韩欧美www| 欧美丝袜自拍制服另类| 成人午夜av在线| 裸体一区二区三区| 一区二区三区美女| 国产三级精品三级在线专区| 欧美巨大另类极品videosbest| 成人丝袜18视频在线观看| 日韩在线观看一区二区| 亚洲精品水蜜桃| 久久综合丝袜日本网| 欧美日韩国产综合一区二区三区| 成人av电影免费观看| 黑人精品欧美一区二区蜜桃| 亚洲chinese男男1069| 国产精品久久久久影视| 欧美精品一区二区久久久| 欧美日韩美少妇 | 欧美三级电影网站| 不卡视频在线观看| 韩国中文字幕2020精品| 日韩中文字幕一区二区三区| 一个色妞综合视频在线观看| 欧美高清在线视频| 国产日韩v精品一区二区| 欧美一区二区三区四区久久 | 欧美伦理影视网| 91黄色免费观看| 91片黄在线观看| 成人涩涩免费视频| 国产资源精品在线观看| 国内精品伊人久久久久av一坑 | 在线播放日韩导航| 欧美日韩一卡二卡三卡| 日本精品裸体写真集在线观看 | 日韩精品在线看片z| 91精品国产全国免费观看| 欧美精品三级在线观看| 欧美无乱码久久久免费午夜一区| 91福利国产成人精品照片| 色婷婷av一区二区三区之一色屋| 91啪九色porn原创视频在线观看| 91网址在线看| 在线看国产日韩| 欧美三级日本三级少妇99| 欧美日韩亚洲综合一区二区三区| 欧美日韩高清在线| 51精品秘密在线观看| 91精品国产综合久久精品app| 欧美日韩五月天| 欧美一级久久久久久久大片| 日韩一级片网站| 日韩欧美区一区二| 国产欧美精品国产国产专区| 国产精品久久久久久久久搜平片 | 国产精品系列在线观看| 国产成人8x视频一区二区 | 亚洲卡通欧美制服中文| 夜夜爽夜夜爽精品视频| 日本vs亚洲vs韩国一区三区二区 | 亚洲激情在线激情| 亚洲va天堂va国产va久| 久久精品久久综合| 成人一区在线看| 在线观看一区二区视频| 3atv在线一区二区三区| 欧美精品一区在线观看| 国产精品国产三级国产有无不卡| 一区二区三区欧美久久| 麻豆精品一区二区| 国产成+人+日韩+欧美+亚洲| 色av成人天堂桃色av| 91精品国产91综合久久蜜臀| 久久精品夜色噜噜亚洲a∨| 亚洲老司机在线| 国内精品写真在线观看| 91免费版在线看| 日韩小视频在线观看专区| 日本一区二区视频在线观看| 亚洲韩国一区二区三区| 精久久久久久久久久久| 色综合久久中文字幕| 精品免费日韩av| 亚洲最新视频在线观看| 激情文学综合丁香| 在线亚洲高清视频| 久久精品视频一区二区三区| 亚洲成av人片在线| 国产成a人亚洲| 欧美一区二区三区免费大片| 中文字幕亚洲欧美在线不卡| 美女一区二区视频| 91福利国产成人精品照片| 国产日韩欧美综合一区| 日韩中文字幕不卡| 色老头久久综合| 欧美极品另类videosde| 麻豆免费看一区二区三区| 欧美制服丝袜第一页| 国产精品私人自拍| 蜜桃视频一区二区| 欧美日韩一区二区三区视频| 亚洲婷婷国产精品电影人久久| 久久99热这里只有精品| 欧美日韩精品免费观看视频| 亚洲视频一二区| 粉嫩13p一区二区三区| 日韩一区二区三区电影在线观看 | 亚洲自拍与偷拍| aaa亚洲精品| 欧美激情一区二区三区蜜桃视频| 免费成人在线网站| 9191成人精品久久| 亚洲国产成人91porn| 一本大道综合伊人精品热热| 国产精品色噜噜| 国产精品一区二区免费不卡| 精品国产免费视频| 麻豆成人久久精品二区三区红| 在线观看91精品国产麻豆| 亚洲一区欧美一区| 欧美三级电影网站| 亚洲一区视频在线| 欧美午夜一区二区三区免费大片| 日韩一区欧美小说| 97久久精品人人做人人爽| 中文字幕一区二区三区乱码在线| 成人动漫一区二区在线| 国产精品视频观看| 91在线观看地址| 亚洲视频免费在线观看| 色综合久久综合网97色综合| 亚洲欧洲日本在线| 色偷偷成人一区二区三区91| 亚洲精品国产一区二区精华液| 一本高清dvd不卡在线观看| 亚洲免费大片在线观看| 欧洲色大大久久| 日韩电影一区二区三区| 日韩一级黄色片| 国产精品一二三区| 国产精品美女久久久久aⅴ| 99久久精品国产导航| 一区二区三区四区国产精品| 欧美人动与zoxxxx乱| 麻豆91精品视频| 六月丁香婷婷久久| 欧美精品一区二区三区在线播放| 国产激情视频一区二区三区欧美 | 5566中文字幕一区二区电影| 日本欧美肥老太交大片| 2020日本不卡一区二区视频| 国产美女精品在线| 国产精品激情偷乱一区二区∴| 91久久精品国产91性色tv| 日本中文字幕不卡| 国产日韩欧美综合在线| 99v久久综合狠狠综合久久| 亚洲sss视频在线视频| 欧美成人r级一区二区三区| 国产馆精品极品|