コード例 #1
0
ファイル: psp2-context.c プロジェクト: leiradel/mgba
static THREAD_ENTRY _audioThread(void* context) {
	struct mPSP2AudioContext* audio = (struct mPSP2AudioContext*) context;
	uint32_t zeroBuffer[PSP2_SAMPLES] = {0};
	void* buffer = zeroBuffer;
	int audioPort = sceAudioOutOpenPort(SCE_AUDIO_OUT_PORT_TYPE_MAIN, PSP2_SAMPLES, 48000, SCE_AUDIO_OUT_MODE_STEREO);
	while (audio->running) {
		MutexLock(&audio->mutex);
		if (buffer != zeroBuffer) {
			// Can only happen in successive iterations
			audio->samples -= PSP2_SAMPLES;
			ConditionWake(&audio->cond);
		}
		if (audio->samples >= PSP2_SAMPLES) {
			buffer = &audio->buffer[audio->readOffset];
			audio->readOffset += PSP2_SAMPLES;
			if (audio->readOffset >= PSP2_AUDIO_BUFFER_SIZE) {
				audio->readOffset = 0;
			}
			// Don't mark samples as read until the next loop iteration to prevent
			// writing to the buffer while being read (see above)
		} else {
			buffer = zeroBuffer;
		}
		MutexUnlock(&audio->mutex);

		sceAudioOutOutput(audioPort, buffer);
	}
	sceAudioOutReleasePort(audioPort);
	return 0;
}
コード例 #2
0
ファイル: sync.c プロジェクト: netux79/mgba
void GBASyncConsumeAudio(struct GBASync* sync) {
	if (!sync) {
		return;
	}

	ConditionWake(&sync->audioRequiredCond);
	MutexUnlock(&sync->audioBufferMutex);
}
コード例 #3
0
ファイル: lockstep.c プロジェクト: joolswills/mgba
bool GBASIOLockstepNodeUnload(struct GBASIODriver* driver) {
    struct GBASIOLockstepNode* node = (struct GBASIOLockstepNode*) driver;
    MutexLock(&node->p->mutex);
    --node->p->loaded;
    ConditionWake(&node->p->barrier);
    MutexUnlock(&node->p->mutex);
    return true;
}
コード例 #4
0
ファイル: sync.c プロジェクト: netux79/mgba
static void _changeVideoSync(struct GBASync* sync, bool frameOn) {
	// Make sure the video thread can process events while the GBA thread is paused
	MutexLock(&sync->videoFrameMutex);
	if (frameOn != sync->videoFrameOn) {
		sync->videoFrameOn = frameOn;
		ConditionWake(&sync->videoFrameAvailableCond);
	}
	MutexUnlock(&sync->videoFrameMutex);
}
コード例 #5
0
ファイル: sync.c プロジェクト: netux79/mgba
void GBASyncForceFrame(struct GBASync* sync) {
	if (!sync) {
		return;
	}

	MutexLock(&sync->videoFrameMutex);
	ConditionWake(&sync->videoFrameAvailableCond);
	MutexUnlock(&sync->videoFrameMutex);
}
コード例 #6
0
ファイル: sync.c プロジェクト: netux79/mgba
void GBASyncPostFrame(struct GBASync* sync) {
	if (!sync) {
		return;
	}

	MutexLock(&sync->videoFrameMutex);
	++sync->videoFramePending;
	--sync->videoFrameSkip;
	if (sync->videoFrameSkip < 0) {
		do {
			ConditionWake(&sync->videoFrameAvailableCond);
			if (sync->videoFrameWait) {
				ConditionWait(&sync->videoFrameRequiredCond, &sync->videoFrameMutex);
			}
		} while (sync->videoFrameWait && sync->videoFramePending);
	}
	MutexUnlock(&sync->videoFrameMutex);
}
コード例 #7
0
ファイル: sync.c プロジェクト: netux79/mgba
bool GBASyncWaitFrameStart(struct GBASync* sync, int frameskip) {
	if (!sync) {
		return true;
	}

	MutexLock(&sync->videoFrameMutex);
	ConditionWake(&sync->videoFrameRequiredCond);
	if (!sync->videoFrameOn && !sync->videoFramePending) {
		return false;
	}
	if (sync->videoFrameOn) {
		if (ConditionWaitTimed(&sync->videoFrameAvailableCond, &sync->videoFrameMutex, 50)) {
			return false;
		}
	}
	sync->videoFramePending = 0;
	sync->videoFrameSkip = frameskip;
	return true;
}