mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
port: revert multithreaded audio experiments
until I can figure out how to fix all the funny concurrency issues that cropped up
This commit is contained in:
1 parent
dce96a4a3d
commit
de3b8ff548
16 files changed
+62
-174
No files matched your search
+2
-2
@@ -150,7 +150,7 @@ B_DIR := build/$(ROMID)-port
|
||||
G_DIR := src/generated/$(ROMID)
|
||||
|
||||
ifneq (,$(findstring windows,$(TARGET_PLATFORM)))
|
||||
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) -pthread
|
||||
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I)
|
||||
TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lz -lopengl32 -ldbghelp
|
||||
# on windows/mingw we need this to be built with a 32-bit compiler so it finds the correct libs
|
||||
TOOLCHAIN ?= i686-w64-mingw32-
|
||||
@@ -161,7 +161,7 @@ ifneq (,$(findstring windows,$(TARGET_PLATFORM)))
|
||||
TARGET_LDFLAGS += -lstdc++
|
||||
endif
|
||||
else # assume *nix
|
||||
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) -pthread
|
||||
TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I)
|
||||
TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lGL -lz -ldl
|
||||
ifneq (,$(findstring arm,$(TARGET_PLATFORM))$(findstring aarch,$(TARGET_PLATFORM)))
|
||||
# linux on arm or aarch64
|
||||
|
||||
@@ -261,7 +261,7 @@ static inline void sync_framerate_with_timer(void) {
|
||||
// We want to exit a bit early, so we can busy-wait the rest to never miss the deadline
|
||||
left -= 15000UL;
|
||||
if (left > 0) {
|
||||
sysFrameLimiterSleep(left);
|
||||
sysSleep(left);
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
s32 audioInit(void);
|
||||
s32 audioGetBytesBuffered(void);
|
||||
s32 audioGetSamplesBuffered(void);
|
||||
void audioSubmitBuffer(const s16 *buf, u32 size);
|
||||
void audioSetNextBuffer(const s16 *buf, u32 len);
|
||||
void audioEndFrame(void);
|
||||
|
||||
#endif
|
||||
@@ -35,11 +35,7 @@ void *sysMemZeroAlloc(const u32 size);
|
||||
void sysMemFree(void *ptr);
|
||||
|
||||
// hns is specified in 100ns units
|
||||
// do not use sysFrameLimiterSleep on any thread other than the main one
|
||||
void sysFrameLimiterSleep(const s64 hns);
|
||||
|
||||
// us is specified in microseconds
|
||||
void sysSleep(const s64 us);
|
||||
void sysSleep(const s64 hns);
|
||||
|
||||
// yield CPU if supported (e.g. during a busy loop)
|
||||
void sysCpuRelax(void);
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#ifndef _IN_THREAD_H
|
||||
#define _IN_THREAD_H
|
||||
|
||||
#include <PR/ultratypes.h>
|
||||
#include "platform.h"
|
||||
|
||||
// TODO: backends
|
||||
#ifndef PLATFORM_USE_PTHREAD
|
||||
#error "No available thread backend."
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define SYSMUTEX_STATIC_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
typedef pthread_t systhread;
|
||||
typedef pthread_mutex_t sysmutex;
|
||||
|
||||
typedef void *(*systhreadfn)(void *);
|
||||
|
||||
s32 sysThreadCreate(systhread *thread, systhreadfn func, void *arg);
|
||||
s32 sysThreadJoin(systhread *thread, void **result);
|
||||
|
||||
void sysMutexLock(sysmutex *mtx);
|
||||
void sysMutexUnlock(sysmutex *mtx);
|
||||
|
||||
#endif // _IN_THREAD_H
|
||||
+16
-24
@@ -7,13 +7,12 @@
|
||||
#include "system.h"
|
||||
|
||||
static SDL_AudioDeviceID dev;
|
||||
static const s16 *nextBuf;
|
||||
static u32 nextSize = 0;
|
||||
|
||||
static s32 bufferSize = 512;
|
||||
static s32 queueLimit = 8192;
|
||||
|
||||
static f32 offsetFrames = 0.5f;
|
||||
static u32 offsetBytes;
|
||||
|
||||
s32 audioInit(void)
|
||||
{
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) {
|
||||
@@ -29,8 +28,7 @@ s32 audioInit(void)
|
||||
want.samples = bufferSize;
|
||||
want.callback = NULL;
|
||||
|
||||
const f32 spf = (f32)want.freq / (PAL ? 50.f : 60.f);
|
||||
offsetBytes = offsetFrames * spf * (f32)sizeof(int16_t);
|
||||
nextBuf = NULL;
|
||||
|
||||
dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
|
||||
if (dev == 0) {
|
||||
@@ -45,39 +43,33 @@ s32 audioInit(void)
|
||||
|
||||
s32 audioGetBytesBuffered(void)
|
||||
{
|
||||
u32 count = SDL_GetQueuedAudioSize(dev);
|
||||
|
||||
// pd's audio code decides how many samples of audio to produce based on the amount of audio
|
||||
// currently buffered, so we adjust the reported count to be some number of frames in the future
|
||||
// to counteract lag; idea shamelessly stolen from mm recomp
|
||||
if (offsetBytes) {
|
||||
if (count > offsetBytes) {
|
||||
count -= offsetBytes;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
return SDL_GetQueuedAudioSize(dev);
|
||||
}
|
||||
|
||||
s32 audioGetSamplesBuffered(void)
|
||||
{
|
||||
return audioGetBytesBuffered() / (2 * sizeof(s16));
|
||||
return audioGetBytesBuffered() / 4;
|
||||
}
|
||||
|
||||
void audioSubmitBuffer(const s16 *buf, u32 size)
|
||||
void audioSetNextBuffer(const s16 *buf, u32 len)
|
||||
{
|
||||
if (buf && size) {
|
||||
nextBuf = buf;
|
||||
nextSize = len;
|
||||
}
|
||||
|
||||
void audioEndFrame(void)
|
||||
{
|
||||
if (nextBuf && nextSize) {
|
||||
if (audioGetSamplesBuffered() < queueLimit) {
|
||||
SDL_QueueAudio(dev, buf, size);
|
||||
SDL_QueueAudio(dev, nextBuf, nextSize);
|
||||
}
|
||||
nextBuf = NULL;
|
||||
nextSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PD_CONSTRUCTOR static void audioConfigInit(void)
|
||||
{
|
||||
configRegisterInt("Audio.BufferSize", &bufferSize, 0, 1 * 1024 * 1024);
|
||||
configRegisterFloat("Audio.OffsetFrames", &offsetFrames, 0.f, 5.f);
|
||||
configRegisterInt("Audio.QueueLimit", &queueLimit, 0, 1 * 1024 * 1024);
|
||||
}
|
||||
+1
-1
@@ -166,7 +166,7 @@ u32 osAiGetLength(void)
|
||||
|
||||
s32 osAiSetNextBuffer(void *bufPtr, u32 size)
|
||||
{
|
||||
audioSubmitBuffer(bufPtr, size);
|
||||
audioSetNextBuffer(bufPtr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -501,7 +501,7 @@ void mainLoop(void)
|
||||
schedEndFrame(&g_Sched);
|
||||
}
|
||||
if (g_TickExtraSleep) {
|
||||
sysFrameLimiterSleep(EXTRA_SLEEP_TIME);
|
||||
sysSleep(EXTRA_SLEEP_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,6 +242,18 @@ void schedStartFrame(OSSched *sc)
|
||||
videoStartFrame();
|
||||
}
|
||||
|
||||
void schedAudioFrame(OSSched *sc)
|
||||
{
|
||||
s32 i;
|
||||
|
||||
if (!g_SndDisabled) {
|
||||
for (i = 0; i < g_Vars.diffframe60; i++) {
|
||||
amgrFrame();
|
||||
audioEndFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a retrace (vsync) event.
|
||||
*
|
||||
@@ -260,6 +272,18 @@ void schedEndFrame(OSSched *sc)
|
||||
{
|
||||
sc->frameCount++;
|
||||
|
||||
#if PAL
|
||||
if (!g_Resetting && (sc->frameCount & 1)) {
|
||||
// osStopTimer(&g_SchedRspTimer);
|
||||
// osSetTimer(&g_SchedRspTimer, 280000, 0, amgrGetFrameMesgQueue(), &g_SchedRspMsg);
|
||||
}
|
||||
#else
|
||||
if (!g_Resetting && ((sc->frameCount & 1) || IS4MB())) {
|
||||
// osStopTimer(&g_SchedRspTimer);
|
||||
// osSetTimer(&g_SchedRspTimer, 280000, 0, amgrGetFrameMesgQueue(), &g_SchedRspMsg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!g_Resetting) {
|
||||
viHandleRetrace();
|
||||
}
|
||||
@@ -271,6 +295,7 @@ void schedEndFrame(OSSched *sc)
|
||||
joy00014238();
|
||||
|
||||
sndHandleRetrace();
|
||||
schedAudioFrame(sc);
|
||||
schedRenderCrashPeriodically(sc->frameCount);
|
||||
videoEndFrame();
|
||||
|
||||
|
||||
+3
-8
@@ -9,7 +9,6 @@
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <SDL.h>
|
||||
#include <PR/ultratypes.h>
|
||||
#include "platform.h"
|
||||
@@ -33,6 +32,8 @@ __attribute__((dllexport)) u32 AmdPowerXpressRequestHighPerformance = 1;
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
// figure out how to yield
|
||||
#if defined(PLATFORM_X86) || defined(PLATFORM_X86_64)
|
||||
// this should work even if the code is not built with SSE enabled, at least on gcc and clang,
|
||||
@@ -292,7 +293,7 @@ void sysMemFree(void *ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void sysFrameLimiterSleep(const s64 hns)
|
||||
void sysSleep(const s64 hns)
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
static LARGE_INTEGER li;
|
||||
@@ -305,12 +306,6 @@ void sysFrameLimiterSleep(const s64 hns)
|
||||
#endif
|
||||
}
|
||||
|
||||
void sysSleep(const s64 us)
|
||||
{
|
||||
const struct timespec spec = { 0, us * 1000 };
|
||||
nanosleep(&spec, NULL);
|
||||
}
|
||||
|
||||
void sysCpuRelax(void)
|
||||
{
|
||||
DO_YIELD();
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#include "thread.h"
|
||||
|
||||
#ifndef PLATFORM_USE_PTHREAD
|
||||
#error "No available thread backend."
|
||||
#endif
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
s32 sysThreadCreate(systhread *thread, systhreadfn func, void *arg)
|
||||
{
|
||||
return pthread_create(thread, NULL, func, arg);
|
||||
}
|
||||
|
||||
s32 sysThreadJoin(systhread *thread, void **result)
|
||||
{
|
||||
return pthread_join(*thread, result);
|
||||
}
|
||||
|
||||
void sysMutexLock(sysmutex *mtx)
|
||||
{
|
||||
pthread_mutex_lock(mtx);
|
||||
}
|
||||
|
||||
void sysMutexUnlock(sysmutex *mtx)
|
||||
{
|
||||
pthread_mutex_unlock(mtx);
|
||||
}
|
||||
@@ -9840,14 +9840,20 @@ bool aiIfMusicEventQueueIsEmpty(void)
|
||||
{
|
||||
f32 value = (u64)osGetCount() * 64 / 3000;
|
||||
|
||||
#ifdef PLATFORM_N64 // will hang forever until the audio thread wakes it up
|
||||
if (g_MusicEventQueueLength) {
|
||||
#ifndef PLATFORM_N64
|
||||
musicTickEvents();
|
||||
#else // HACK: will wait 1 frame and get on with it
|
||||
static bool waited = false;
|
||||
if (g_MusicEventQueueLength && !waited) {
|
||||
waited = true;
|
||||
#endif
|
||||
g_Vars.aioffset += 4;
|
||||
} else {
|
||||
u8 *cmd = g_Vars.ailist + g_Vars.aioffset;
|
||||
g_Vars.aioffset = chraiGoToLabel(g_Vars.ailist, g_Vars.aioffset, cmd[3]);
|
||||
#ifndef PLATFORM_N64
|
||||
waited = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ void frametimeCalculate(void)
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
if (g_TickExtraSleep) {
|
||||
sysFrameLimiterSleep(EXTRA_SLEEP_TIME);
|
||||
sysSleep(EXTRA_SLEEP_TIME);
|
||||
}
|
||||
#endif
|
||||
} while (g_Vars.mininc60 && diffframe60 < g_Vars.mininc60);
|
||||
|
||||
@@ -17,11 +17,7 @@ OSMesgQueue *amgrGetFrameMesgQueue(void);
|
||||
void amgrStopThread(void);
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
void amgrLock(void);
|
||||
void amgrUnlock(void);
|
||||
#else
|
||||
#define amgrLock() do {} while(0)
|
||||
#define amgrUnlock() do {} while(0)
|
||||
void amgrFrame(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -34,9 +34,6 @@
|
||||
#error "64-bit platforms are currently not supported."
|
||||
#endif
|
||||
|
||||
// threading backend
|
||||
#define PLATFORM_USE_PTHREAD 1
|
||||
|
||||
// detect endianness
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
@@ -10,13 +10,6 @@
|
||||
#include "lib/libc/ll.h"
|
||||
#include "data.h"
|
||||
#include "types.h"
|
||||
#ifndef PLATFORM_N64
|
||||
#include "lib/audiomgr.h"
|
||||
#include "thread.h"
|
||||
#include "audio.h"
|
||||
#include "system.h"
|
||||
#define AMGR_THREAD_SLEEP_US 2000
|
||||
#endif
|
||||
|
||||
u32 var80091560;
|
||||
u32 var80091564;
|
||||
@@ -50,14 +43,6 @@ void *g_AudioSp;
|
||||
u32 var8005cf90 = 0x00000000;
|
||||
u8 var8005cf94 = 1;
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
systhread g_AmgrThread;
|
||||
sysmutex g_AmgrMutex = SYSMUTEX_STATIC_INIT;
|
||||
u32 g_AmgrFrame;
|
||||
u32 g_AmgrFrameTarget;
|
||||
void *amgrThread(void *arg);
|
||||
#endif
|
||||
|
||||
void amgrHandleDoneMsg(AudioInfo *info);
|
||||
void amgrHandleFrameMsg(AudioInfo *info, AudioInfo *previnfo);
|
||||
void amgrMain(void *arg);
|
||||
@@ -170,9 +155,6 @@ void amgrStartThread(void)
|
||||
{
|
||||
osStartThread(&g_AudioManager.thread);
|
||||
g_AudioIsThreadRunning = true;
|
||||
#ifndef PLATFORM_N64
|
||||
sysThreadCreate(&g_AmgrThread, &amgrThread, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
OSMesgQueue *amgrGetFrameMesgQueue(void)
|
||||
@@ -189,12 +171,6 @@ void amgrStopThread(void)
|
||||
{
|
||||
if (g_AudioIsThreadRunning) {
|
||||
osStopThread(&g_AudioManager.thread);
|
||||
#ifndef PLATFORM_N64
|
||||
amgrLock();
|
||||
g_AudioIsThreadRunning = false;
|
||||
amgrUnlock();
|
||||
sysThreadJoin(&g_AmgrThread, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,14 +321,11 @@ void amgrHandleDoneMsg(AudioInfo *info)
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_N64
|
||||
|
||||
void amgrFrame(void)
|
||||
{
|
||||
static AudioInfo *previnfo = NULL;
|
||||
static s32 count = 0;
|
||||
|
||||
amgrLock();
|
||||
|
||||
var80091588 = osGetTime();
|
||||
|
||||
AudioInfo *info = g_AudioManager.audioInfo[g_AdmaCurFrame % 3];
|
||||
@@ -390,8 +363,6 @@ void amgrFrame(void)
|
||||
|
||||
count++;
|
||||
|
||||
amgrUnlock();
|
||||
|
||||
var80091590 = osGetTime();
|
||||
var80091570 = var80091590 - var80091588;
|
||||
|
||||
@@ -406,41 +377,4 @@ void amgrFrame(void)
|
||||
var80091568 = var80091590 - var80091588;
|
||||
}
|
||||
}
|
||||
|
||||
void amgrLock(void)
|
||||
{
|
||||
sysMutexLock(&g_AmgrMutex);
|
||||
}
|
||||
|
||||
void amgrUnlock(void)
|
||||
{
|
||||
sysMutexUnlock(&g_AmgrMutex);
|
||||
}
|
||||
|
||||
void *amgrThread(void *arg)
|
||||
{
|
||||
const f64 frametime = 1000000.0 / (PAL ? 50.0 : 60.0);
|
||||
bool running = g_AudioIsThreadRunning;
|
||||
f64 nexttick = sysGetMicroseconds();
|
||||
f64 tick;
|
||||
|
||||
while (running) {
|
||||
tick = sysGetMicroseconds() + 0.01;
|
||||
|
||||
while (nexttick < tick) {
|
||||
amgrFrame();
|
||||
g_AmgrFrame++;
|
||||
nexttick += frametime;
|
||||
}
|
||||
|
||||
sysSleep(AMGR_THREAD_SLEEP_US);
|
||||
|
||||
amgrLock();
|
||||
running = g_AudioIsThreadRunning;
|
||||
amgrUnlock();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user