예제 #1
0
static void DS_Update(void)
{
	LPVOID block;
	DWORD bBytes;

	/* Do first update in DS_Update() to be consistent with other
	   non threaded drivers. */
	if (do_update && pSoundBuffer) {
		do_update = 0;

		if (pSoundBuffer->lpVtbl->Lock (pSoundBuffer, 0, fragsize,
										&block, &bBytes, NULL, NULL, 0)
				== DSERR_BUFFERLOST) {
			pSoundBuffer->lpVtbl->Restore (pSoundBuffer);
			pSoundBuffer->lpVtbl->Lock (pSoundBuffer, 0, fragsize,
										&block, &bBytes, NULL, NULL, 0);
		}

		if (Player_Paused_internal()) {
			VC_SilenceBytes ((SBYTE *)block, (ULONG)bBytes);
		} else {
			VC_WriteBytes ((SBYTE *)block, (ULONG)bBytes);
		}

		pSoundBuffer->lpVtbl->Unlock (pSoundBuffer, block, bBytes, NULL, 0);

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

		threadInUse=1;
		ResumeThread (updateBufferHandle);
	}
}
예제 #2
0
static void XAudio2_Update(void) {
	if (do_update && pSourceVoice) {
		do_update = 0;

		while (1) {
			XAUDIO2_VOICE_STATE state;
			XAUDIO2_BUFFER audio_buf;

			#if !defined(DRV_XAUDIO28)
			IXAudio2SourceVoice_GetState(pSourceVoice, &state);
			#else
			IXAudio2SourceVoice_GetState(pSourceVoice, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
			#endif
			if (state.BuffersQueued > 0)
				break;
			current_buf %= XAUDIO2_NUM_BUFFERS;
			if (Player_Paused_internal())
				VC_SilenceBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			else
				VC_WriteBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			memset(&audio_buf, 0, sizeof(XAUDIO2_BUFFER));
			audio_buf.AudioBytes = XAUDIO2_BUFFER_SIZE;
			audio_buf.pAudioData = buffers[current_buf];
			IXAudio2SourceVoice_SubmitSourceBuffer(pSourceVoice, &audio_buf, NULL);
			current_buf++;
			current_buf %= XAUDIO2_NUM_BUFFERS;
		}
		IXAudio2SourceVoice_Start(pSourceVoice, 0, 0);
		threadInUse = 1;
		ResumeThread(UpdateBufferHandle);
	}
}
예제 #3
0
static DWORD WINAPI UpdateBufferProc(LPVOID lpParameter) {
	while (threadInUse) {
		while (1) {
			XAUDIO2_VOICE_STATE state;
			XAUDIO2_BUFFER audio_buf;

			#if !defined(DRV_XAUDIO28)
			IXAudio2SourceVoice_GetState(pSourceVoice, &state);
			#else
			IXAudio2SourceVoice_GetState(pSourceVoice, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
			#endif
			if (state.BuffersQueued >= XAUDIO2_NUM_BUFFERS - 1)
				break;
			MUTEX_LOCK(vars);
			if (Player_Paused_internal())
				VC_SilenceBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			else
				VC_WriteBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			MUTEX_UNLOCK(vars);
			memset(&audio_buf, 0, sizeof(XAUDIO2_BUFFER));
			audio_buf.AudioBytes = XAUDIO2_BUFFER_SIZE;
			audio_buf.pAudioData = buffers[current_buf];
			IXAudio2SourceVoice_SubmitSourceBuffer(pSourceVoice, &audio_buf, NULL);
			current_buf++;
			current_buf %= XAUDIO2_NUM_BUFFERS;
		}
		WaitForSingleObject(hBufferEvent, INFINITE);
	}
	return 0;
}
예제 #4
0
static void WSS_Callback(void)
{
	unsigned int dma_size, dma_pos;
	ULONG (*mixer)(SBYTE *buf, ULONG todo);

	wss_query_dma(&dma_size, &dma_pos);
	/* There isn't much sense in filling less than 256 bytes */
	dma_pos &= ~255;

	/* If nothing to mix, quit */
	if (buff_tail == dma_pos)
		return;

	if (Player_Paused_internal())
		mixer = VC_SilenceBytes;
	else
		mixer = VC_WriteBytes;

	/* If DMA pointer still didn't wrapped around ... */
	if (dma_pos > buff_tail) {
		buff_tail += mixer (wss.dma_buff->linear + buff_tail, dma_pos - buff_tail);
		/* If we arrived right to the DMA buffer end, jump to the beginning */
		if (buff_tail >= dma_size)
			buff_tail = 0;
	} else {
		/* If wrapped around, fill first to the end of buffer */
		mixer (wss.dma_buff->linear + buff_tail, dma_size - buff_tail);
		/* Now fill from buffer beginning to current DMA pointer */
		buff_tail = mixer (wss.dma_buff->linear, dma_pos);
	}
}
예제 #5
0
static DWORD WINAPI updateBufferProc(LPVOID lpParameter)
{
	LPVOID pBlock1 = NULL, pBlock2 = NULL;
	DWORD soundBufferCurrentPosition, blockBytes1, blockBytes2;
	DWORD start;

	while (threadInUse) {
		if (WaitForSingleObject(notifyUpdateHandle,INFINITE)==WAIT_OBJECT_0) {

			if (!threadInUse) break;

			pSoundBuffer->lpVtbl->GetCurrentPosition
						(pSoundBuffer,&soundBufferCurrentPosition,NULL);

			if (soundBufferCurrentPosition < fragsize)
				start = fragsize;
			else
				start = 0;

			if (pSoundBuffer->lpVtbl->Lock
						(pSoundBuffer,start,fragsize,&pBlock1,&blockBytes1,
						 &pBlock2,&blockBytes2,0)==DSERR_BUFFERLOST) {	
				pSoundBuffer->lpVtbl->Restore(pSoundBuffer);
				pSoundBuffer->lpVtbl->Lock
						(pSoundBuffer,start,fragsize,&pBlock1,&blockBytes1,
						 &pBlock2,&blockBytes2,0);
			}

			MUTEX_LOCK(vars);
			if (Player_Paused_internal()) {
				VC_SilenceBytes((SBYTE*)pBlock1,(ULONG)blockBytes1);
				if (pBlock2)
					VC_SilenceBytes((SBYTE*)pBlock2,(ULONG)blockBytes2);
			} else {
				VC_WriteBytes((SBYTE*)pBlock1,(ULONG)blockBytes1);
				if (pBlock2)
					VC_WriteBytes((SBYTE*)pBlock2,(ULONG)blockBytes2);
			}
			MUTEX_UNLOCK(vars);
			
			pSoundBuffer->lpVtbl->Unlock
						(pSoundBuffer,pBlock1,blockBytes1,pBlock2,blockBytes2);
		}
	}
	return 0;
}
예제 #6
0
/* ARGSUSED */
void OS2_UpdateBufferThread(void *dummy)
{
	/* Run at timecritical priority */
	DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, PRTYD_MAXIMUM - 1, 0);

	while (!FinishPlayback) {
		ULONG count;
static	ULONG NextBuffer = 0;	/* next fragment to be filled */

		/* wait for play enable */
		DosWaitEventSem(Play, SEM_INDEFINITE_WAIT);
		/* wait for timer event */
		DosWaitEventSem(Update, SEM_INDEFINITE_WAIT);
		/* reset timer semaphore */
		DosResetEventSem(Update, &count);

		/* fill all free buffers */
		while (PlayList[NextBuffer].ulOperand3 >=
			   PlayList[NextBuffer].ulOperand2) {
			MUTEX_LOCK(vars);
			if (Player_Paused_internal())
				PlayList[NextBuffer].ulOperand2 =
				  VC_SilenceBytes((SBYTE *)PlayList[NextBuffer].ulOperand1,
								  BufferSize);
			else
				PlayList[NextBuffer].ulOperand2 =
				  VC_WriteBytes((SBYTE *)PlayList[NextBuffer].ulOperand1,
								BufferSize);
			MUTEX_UNLOCK(vars);
			/* Reset play offset, although it seems MMOS2 does it
			   automagically */
			PlayList[NextBuffer].ulOperand3 = 0;
			NextBuffer = (NextBuffer + 1) % FRAGMENTS;
		}
	}
	/* Tell main thread we're done */
	ThreadID = 0;
}
예제 #7
0
/* Buffer update thread (created and called by DART)
   This is a high-priority thread used to compute and update the audio stream,
   automatically created by the DART subsystem. We compute the next audio
   buffer and feed it to the waveaudio device. */
static LONG APIENTRY Dart_UpdateBuffers(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
{
	/* sanity check */
	if (!pBuffer)
		return TRUE;
	
	/* if we have finished a buffer, we're ready to play a new one */
	if ((ulFlags == MIX_WRITE_COMPLETE) ||
		((ulFlags == (MIX_WRITE_COMPLETE | MIX_STREAM_ERROR)) &&
		 (ulStatus == ERROR_DEVICE_UNDERRUN))) {
		/* refill this audio buffer and feed it again */
		MUTEX_LOCK(vars);
		if (Player_Paused_internal())
			pBuffer->ulBufferLength =
					VC_SilenceBytes(pBuffer->pBuffer, BufferSize);
		else
			pBuffer->ulBufferLength =
					VC_WriteBytes(pBuffer->pBuffer, BufferSize);
		MUTEX_UNLOCK(vars);
		MixSetupParms.pmixWrite(MixSetupParms.ulMixHandle, pBuffer, 1);
	}
	return TRUE;
}