//-----------------------------------------------------------------------------
// Name: idWaveFile::Close()
// Desc: Closes the wave file
//-----------------------------------------------------------------------------
int idWaveFile::Close(void)
{
	if (ogg != NULL) {
		return CloseOGG();
	}

	if (mhmmio != NULL) {
		fileSystem->CloseFile(mhmmio);
		mhmmio = NULL;
	}

	return 0;
}
Beispiel #2
0
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)))
	{
		Con_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)
		CDAudio_Play(playTrack, true);	

	return 0;
}