X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fdfsound%2Fspu.c;h=c6a06fd446072b7dc87dbb6de0b97e1169978f93;hp=96ef69c5be7e8919a7724ba0180b005f7167fc69;hb=de4a0279efefdd2e4595c8fc27f1564f4bff9341;hpb=5514a050f4e936f5c333fa1271b11bf5a6a9ea39 diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index 96ef69c5..c6a06fd4 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -18,7 +18,7 @@ * * ***************************************************************************/ -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(NO_OS) #include // gettimeofday in xa.c #define THREAD_ENABLED 1 #endif @@ -29,9 +29,12 @@ #include "externals.h" #include "registers.h" #include "out.h" -#include "arm_features.h" #include "spu_config.h" +#ifdef __arm__ +#include "arm_features.h" +#endif + #ifdef __ARM_ARCH_7A__ #define ssat32_to_16(v) \ asm("ssat %0,#16,%1" : "=r" (v) : "r" (v)) @@ -74,19 +77,18 @@ SPUConfig spu_config; REVERBInfo rvb; -#ifdef THREAD_ENABLED +#if defined(THREAD_ENABLED) || defined(WANT_THREAD_CODE) // worker thread state static struct spu_worker { unsigned int pending:1; unsigned int exit_thread:1; + unsigned int stale_cache:1; int ns_to; int ctrl; int decode_pos; int silentch; unsigned int chmask; - unsigned int r_chan_end; - unsigned int r_decode_dirty; struct { int spos; int sbpos; @@ -97,6 +99,14 @@ static struct spu_worker { ADSRInfoEx adsr; // might want to add vol and fmod flags.. } ch[24]; + struct { + struct { + int adsrState; + int adsrEnvelopeVol; + } ch[24]; + unsigned int chan_end; + unsigned int decode_dirty; + } r; } *worker; #else @@ -260,20 +270,21 @@ static int check_irq(int ch, unsigned char *pos) INLINE void StartSound(int ch) { SPUCHAN *s_chan = &spu.s_chan[ch]; + int *SB = spu.SB + ch * SB_SIZE; StartADSR(ch); StartREVERB(ch); s_chan->prevflags=2; - s_chan->SB[26]=0; // init mixing vars - s_chan->SB[27]=0; s_chan->iSBPos=27; + SB[26]=0; // init mixing vars + SB[27]=0; - s_chan->SB[28]=0; - s_chan->SB[29]=0; // init our interpolation helpers - s_chan->SB[30]=0; - s_chan->SB[31]=0; + SB[28]=0; + SB[29]=0; // init our interpolation helpers + SB[30]=0; + SB[31]=0; s_chan->spos=0; spu.dwNewChannel&=~(1<SB; + SB = spu.SB + ch * SB_SIZE; sinc = s_chan->sinc; if (s_chan->bNoise) @@ -867,10 +878,11 @@ static void do_samples_finish(int ns_to, int silentch, int decode_pos); // optional worker thread handling -#ifdef THREAD_ENABLED +#if defined(THREAD_ENABLED) || defined(WANT_THREAD_CODE) static void thread_work_start(void); static void thread_work_wait_sync(void); +static void thread_sync_caches(void); static void queue_channel_work(int ns_to, int silentch) { @@ -927,7 +939,7 @@ static void do_channel_work(void) sinc = worker->ch[ch].sinc; s_chan = &spu.s_chan[ch]; - SB = s_chan->SB; + SB = spu.SB + ch * SB_SIZE; if (s_chan->bNoise) do_lsfr_samples(d, worker->ctrl, &spu.dwNoiseCount, &spu.dwNoiseVal); @@ -945,6 +957,8 @@ static void do_channel_work(void) worker->ch[ch].adsr.EnvelopeVol = 0; memset(&ChanBuf[d], 0, (ns_to - d) * sizeof(ChanBuf[0])); } + worker->r.ch[ch].adsrState = worker->ch[ch].adsr.State; + worker->r.ch[ch].adsrEnvelopeVol = worker->ch[ch].adsr.EnvelopeVol; if (ch == 1 || ch == 3) { @@ -960,15 +974,17 @@ static void do_channel_work(void) mix_chan(0, ns_to, s_chan->iLeftVolume, s_chan->iRightVolume); } - worker->r_chan_end = endmask; - worker->r_decode_dirty = decode_dirty_ch; + worker->r.chan_end = endmask; + worker->r.decode_dirty = decode_dirty_ch; } -static void sync_worker_thread(void) +static void sync_worker_thread(int do_direct) { unsigned int mask; int ch; + if (do_direct) + thread_sync_caches(); if (!worker->pending) return; @@ -981,12 +997,12 @@ static void sync_worker_thread(void) // be sure there was no keyoff while thread was working if (spu.s_chan[ch].ADSRX.State != ADSR_RELEASE) - spu.s_chan[ch].ADSRX.State = worker->ch[ch].adsr.State; - spu.s_chan[ch].ADSRX.EnvelopeVol = worker->ch[ch].adsr.EnvelopeVol; + spu.s_chan[ch].ADSRX.State = worker->r.ch[ch].adsrState; + spu.s_chan[ch].ADSRX.EnvelopeVol = worker->r.ch[ch].adsrEnvelopeVol; } - spu.dwChannelOn &= ~worker->r_chan_end; - spu.decode_dirty_ch |= worker->r_decode_dirty; + spu.dwChannelOn &= ~worker->r.chan_end; + spu.decode_dirty_ch |= worker->r.decode_dirty; do_samples_finish(worker->ns_to, worker->silentch, worker->decode_pos); @@ -995,7 +1011,7 @@ static void sync_worker_thread(void) #else static void queue_channel_work(int ns_to, int silentch) {} -static void sync_worker_thread(void) {} +static void sync_worker_thread(int do_direct) {} #endif // THREAD_ENABLED @@ -1004,7 +1020,7 @@ static void sync_worker_thread(void) {} // here is the main job handler... //////////////////////////////////////////////////////////////////////// -void do_samples(unsigned int cycles_to, int do_sync) +void do_samples(unsigned int cycles_to, int do_direct) { unsigned int mask; int ch, ns_to; @@ -1019,6 +1035,10 @@ void do_samples(unsigned int cycles_to, int do_sync) return; } + do_direct |= (cycle_diff < 64 * 768); + if (worker != NULL) + sync_worker_thread(do_direct); + if (cycle_diff < 2 * 768) return; @@ -1058,9 +1078,6 @@ void do_samples(unsigned int cycles_to, int do_sync) } } - if (worker != NULL) - sync_worker_thread(); - mask = spu.dwNewChannel & 0xffffff; for (ch = 0; mask != 0; ch++, mask >>= 1) { if (mask & 1) @@ -1074,7 +1091,7 @@ void do_samples(unsigned int cycles_to, int do_sync) do_samples_finish(ns_to, silentch, spu.decode_pos); } else { - if (do_sync || worker == NULL || !spu_config.iUseThread) { + if (do_direct || worker == NULL || !spu_config.iUseThread) { do_channels(ns_to); do_samples_finish(ns_to, silentch, spu.decode_pos); } @@ -1320,6 +1337,10 @@ static void thread_work_wait_sync(void) sem_wait(&t.sem_done); } +static void thread_sync_caches(void) +{ +} + static void *spu_worker_thread(void *unused) { while (1) { @@ -1400,6 +1421,7 @@ long CALLBACK SPUinit(void) InitADSR(); spu.s_chan = calloc(MAXCHAN+1, sizeof(spu.s_chan[0])); // channel + 1 infos (1 is security for fmod handling) + spu.SB = calloc(MAXCHAN, sizeof(spu.SB[0]) * SB_SIZE); spu.spuAddr = 0; spu.decode_pos = 0; @@ -1448,6 +1470,8 @@ long CALLBACK SPUshutdown(void) free(spu.spuMemC); spu.spuMemC = NULL; + free(spu.SB); + spu.SB = NULL; free(spu.s_chan); spu.s_chan = NULL;