VERA: get rid of rand() and adapt code

This commit is contained in:
tildearrow 2022-03-10 16:52:59 -05:00
parent 9bd15bd513
commit 2f02e24a2f
3 changed files with 20 additions and 8 deletions

View file

@ -20,6 +20,8 @@ void
psg_reset(struct VERA_PSG* psg) psg_reset(struct VERA_PSG* psg)
{ {
memset(psg->channels, 0, sizeof(psg->channels)); memset(psg->channels, 0, sizeof(psg->channels));
psg->noiseState=1;
psg->noiseOut=0;
} }
void void
@ -52,13 +54,18 @@ render(struct VERA_PSG* psg, int16_t *left, int16_t *right)
{ {
int l = 0; int l = 0;
int r = 0; int r = 0;
// TODO this is a currently speculated noise generation
// as the hardware and sources for it are not out in the public
// and the official emulator just uses rand()
psg->noiseOut=((psg->noiseOut<<1)|(psg->noiseState&1))&63;
psg->noiseState=(psg->noiseState<<1)|(((psg->noiseState>>1)^(psg->noiseState>>2)^(psg->noiseState>>4)^(psg->noiseState>>15))&1);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
struct VERAChannel *ch = &psg->channels[i]; struct VERAChannel *ch = &psg->channels[i];
unsigned new_phase = (ch->phase + ch->freq) & 0x1FFFF; unsigned new_phase = (ch->phase + ch->freq) & 0x1FFFF;
if ((ch->phase & 0x10000) != (new_phase & 0x10000)) { if ((ch->phase & 0x10000) != (new_phase & 0x10000)) {
ch->noiseval = rand() & 63; ch->noiseval = psg->noiseOut;
} }
ch->phase = new_phase; ch->phase = new_phase;
@ -89,10 +96,11 @@ render(struct VERA_PSG* psg, int16_t *left, int16_t *right)
} }
void void
psg_render(struct VERA_PSG* psg, int16_t *buf, unsigned num_samples) psg_render(struct VERA_PSG* psg, int16_t *bufL, int16_t *bufR, unsigned num_samples)
{ {
while (num_samples--) { while (num_samples--) {
render(psg, &buf[0], &buf[1]); render(psg, bufL, bufR);
buf += 2; bufL++;
bufR++;
} }
} }

View file

@ -19,9 +19,10 @@ struct VERAChannel {
}; };
struct VERA_PSG { struct VERA_PSG {
unsigned int noiseState, noiseOut;
struct VERAChannel channels[16]; struct VERAChannel channels[16];
}; };
void psg_reset(struct VERA_PSG* psg); void psg_reset(struct VERA_PSG* psg);
void psg_writereg(struct VERA_PSG* psg, uint8_t reg, uint8_t val); void psg_writereg(struct VERA_PSG* psg, uint8_t reg, uint8_t val);
void psg_render(struct VERA_PSG* psg, int16_t *buf, unsigned num_samples); void psg_render(struct VERA_PSG* psg, int16_t *bufL, int16_t *bufR, unsigned num_samples);

View file

@ -22,10 +22,12 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
extern "C" {
#include "sound/vera_psg.h" #include "sound/vera_psg.h"
#include "sound/vera_pcm.h" #include "sound/vera_pcm.h"
}
#define rWrite(c,a,d) {regPool[(c)*4+(a)]=(d);} #define rWrite(c,a,d) {regPool[(c)*4+(a)]=(d); psg_writereg(psg,((c)*4+(a)),(d));}
#define rWriteLo(c,a,d) rWrite(c,a,(regPool[(c)*4+(a)]&(~0x3f))|((d)&0x3f)) #define rWriteLo(c,a,d) rWrite(c,a,(regPool[(c)*4+(a)]&(~0x3f))|((d)&0x3f))
#define rWriteHi(c,a,d) rWrite(c,a,(regPool[(c)*4+(a)]&(~0xc0))|(((d)<<6)&0xc0)) #define rWriteHi(c,a,d) rWrite(c,a,(regPool[(c)*4+(a)]&(~0xc0))|(((d)<<6)&0xc0))
#define rWriteFIFOVol(d) rWrite(16,0,(regPool[64]&(~0x3f))|((d)&0x3f)) #define rWriteFIFOVol(d) rWrite(16,0,(regPool[64]&(~0x3f))|((d)&0x3f))
@ -58,6 +60,7 @@ const char* DivPlatformVERA::getEffectName(unsigned char effect) {
} }
void DivPlatformVERA::acquire(short* bufL, short* bufR, size_t start, size_t len) { void DivPlatformVERA::acquire(short* bufL, short* bufR, size_t start, size_t len) {
psg_render(psg,bufL+start,bufR+start,len);
} }
void DivPlatformVERA::reset() { void DivPlatformVERA::reset() {