예제 #1
0
파일: cd_win.c 프로젝트: Izhido/qrevpak
void CDAudio_Play(int track, qboolean looping)
{
	// set a loop counter so that this track will change to the
	// looptrack later
	loopcounter = 0;
	CDAudio_Play2(track, looping);
}
예제 #2
0
파일: cd_win.c 프로젝트: Izhido/qrevpak
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (lParam != wDeviceID)
		return 1;

	switch (wParam)
	{
		case MCI_NOTIFY_SUCCESSFUL:
			if (playing)
			{
				playing = false;
				if (playLooping)
				{
					// if the track has played the given number of times,
					// go to the ambient track
					if (++loopcounter >= cd_loopcount->value)
						CDAudio_Play2(cd_looptrack->value, true);
					else
						CDAudio_Play2(playTrack, true);
				}
			}
			break;

		case MCI_NOTIFY_ABORTED:
		case MCI_NOTIFY_SUPERSEDED:
			break;

		case MCI_NOTIFY_FAILURE:
			Com_DPrintf("MCI_NOTIFY_FAILURE\n");
			CDAudio_Stop ();
			cdValid = false;
			break;

		default:
			Com_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
			return 1;
	}

	return 0;
}
예제 #3
0
파일: cd_win.c 프로젝트: Azarien/SoftQuake2
static unsigned int __stdcall PlayingThreadProc(void *arglist)
{
	struct ThreadArgList_t *tal = arglist;

	DSBPOSITIONNOTIFY notifies[BUFFER_PARTS];
	HANDLE events[BUFFER_PARTS+1]; // +1 for StopEvent
	HANDLE endevents[2];
	char *ptr;
	int i;
	DWORD dummy, fillpart;
	DWORD part_size;
	HRESULT hr;
	qboolean more_data;
	qboolean trackPlayedToEnd = false;

	CDAudio_WaitForFinish();
	ResetEvent(cdPlayingFinishedEvent);
	ResetEvent(cdStopEvent);

	part_size = gCDBufSize / BUFFER_PARTS;

	for (i=0; i<BUFFER_PARTS; i++)
	{
		events[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
		notifies[i].dwOffset = i * part_size;
		notifies[i].hEventNotify = events[i];
	}
	events[i] = cdStopEvent;

	pDSBufCD->lpVtbl->GetStatus(pDSBufCD, &dummy);
	if (dummy & DSBSTATUS_BUFFERLOST)
		pDSBufCD->lpVtbl->Restore(pDSBufCD);

	pDSBufCDNotify->lpVtbl->SetNotificationPositions(pDSBufCDNotify, BUFFER_PARTS, notifies);

	if (FAILED(pDSBufCD->lpVtbl->Lock(pDSBufCD, 0, 0, &ptr, &dummy, NULL, NULL, DSBLOCK_ENTIREBUFFER)))
	{
		Com_DPrintf("CDAudio: cannot lock sound buffer.\n");
		return -1;
	}

	if (!PaintSoundOGG(tal, ptr, (BUFFER_PARTS-1)*part_size))
		SetEvent(cdStopEvent);

	pDSBufCD->lpVtbl->Unlock(pDSBufCD, ptr, dummy, NULL, 0);

	pDSBufCD->lpVtbl->SetCurrentPosition(pDSBufCD, 0);
	pDSBufCD->lpVtbl->Play(pDSBufCD, 0, 0, DSBPLAY_LOOPING);

	while(true)
	{
		fillpart = WaitForMultipleObjects(BUFFER_PARTS+1, events, FALSE, 2000);
		if (fillpart >= WAIT_OBJECT_0 && fillpart < WAIT_OBJECT_0 + BUFFER_PARTS)
		{
			fillpart = (fillpart - WAIT_OBJECT_0 + BUFFER_PARTS - 1) % BUFFER_PARTS;
			hr = pDSBufCD->lpVtbl->Lock(pDSBufCD, part_size * fillpart, part_size, &ptr, &dummy, NULL, NULL, 0);
			if (hr == DSERR_BUFFERLOST)
			{
				pDSBufCD->lpVtbl->Restore(pDSBufCD);
				pDSBufCD->lpVtbl->Lock(pDSBufCD, part_size * fillpart, part_size, &ptr, &dummy, NULL, NULL, 0);
			}
			more_data = PaintSoundOGG(tal, ptr, part_size);
			pDSBufCD->lpVtbl->Unlock(pDSBufCD, ptr, dummy, NULL, 0);
			if (!more_data)
			{
				endevents[0] = events[fillpart];
				endevents[1] = cdStopEvent;
				if (WaitForMultipleObjects(2, endevents, FALSE, 2000) == WAIT_OBJECT_0)
					trackPlayedToEnd = true;
				break;
			}
		}
		else
			break;
	}

	pDSBufCD->lpVtbl->Stop(pDSBufCD);
	pDSBufCDNotify->lpVtbl->SetNotificationPositions(pDSBufCDNotify, 0, NULL);
	for (i=0; i<BUFFER_PARTS; i++)
		CloseHandle(events[i]);
	
	CloseOGG(tal);

	playing = false;
	free(arglist);

	SetEvent(cdPlayingFinishedEvent);

	if (trackPlayedToEnd && playLooping)
	{
		// if the track has played the given number of times,
		// go to the ambient track
		if (++loopcounter >= cd_loopcount->value)
			CDAudio_Play2(cd_looptrack->value, true);
		else
			CDAudio_Play2(playTrack, true);
	}
	return 0;
}