Merge pull request #410 from grauw/dispatch-render-samples
Move renderSamples() to DivDispatch implementations.
This commit is contained in:
commit
5adc29906a
16 changed files with 327 additions and 219 deletions
|
|
@ -141,6 +141,22 @@ const char** DivDispatch::getRegisterSheet() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
const void* DivDispatch::getSampleMem(int index) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t DivDispatch::getSampleMemCapacity(int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t DivDispatch::getSampleMemUsage(int index) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DivDispatch::renderSamples() {
|
||||
|
||||
}
|
||||
|
||||
int DivDispatch::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,8 +268,6 @@ const char* DivPlatformQSound::getEffectName(unsigned char effect) {
|
|||
return NULL;
|
||||
}
|
||||
void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
chip.rom_data = parent->qsoundMem;
|
||||
chip.rom_mask = 0xffffff;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
qsound_update(&chip);
|
||||
bufL[h]=chip.out[0];
|
||||
|
|
@ -638,6 +636,51 @@ int DivPlatformQSound::getRegisterPoolDepth() {
|
|||
return 16;
|
||||
}
|
||||
|
||||
const void* DivPlatformQSound::getSampleMem(int index) {
|
||||
return index == 0 ? sampleMem : NULL;
|
||||
}
|
||||
|
||||
size_t DivPlatformQSound::getSampleMemCapacity(int index) {
|
||||
return index == 0 ? 16777216 : 0;
|
||||
}
|
||||
|
||||
size_t DivPlatformQSound::getSampleMemUsage(int index) {
|
||||
return index == 0 ? sampleMemLen : 0;
|
||||
}
|
||||
|
||||
void DivPlatformQSound::renderSamples() {
|
||||
memset(sampleMem,0,getSampleMemCapacity());
|
||||
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int length=s->length8;
|
||||
if (length>65536-16) {
|
||||
length=65536-16;
|
||||
}
|
||||
if ((memPos&0xff0000)!=((memPos+length)&0xff0000)) {
|
||||
memPos=(memPos+0xffff)&0xff0000;
|
||||
}
|
||||
if (memPos>=getSampleMemCapacity()) {
|
||||
logW("out of QSound PCM memory for sample %d!",i);
|
||||
break;
|
||||
}
|
||||
if (memPos+length>=getSampleMemCapacity()) {
|
||||
for (unsigned int i=0; i<getSampleMemCapacity()-(memPos+length); i++) {
|
||||
sampleMem[(memPos+i)^0x8000]=s->data8[i];
|
||||
}
|
||||
logW("out of QSound PCM memory for sample %d!",i);
|
||||
} else {
|
||||
for (int i=0; i<length; i++) {
|
||||
sampleMem[(memPos+i)^0x8000]=s->data8[i];
|
||||
}
|
||||
}
|
||||
s->offQSound=memPos^0x8000;
|
||||
memPos+=length+16;
|
||||
}
|
||||
sampleMemLen=memPos+256;
|
||||
}
|
||||
|
||||
int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
|
|
@ -651,8 +694,10 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned in
|
|||
|
||||
chipClock=60000000;
|
||||
rate = qsound_start(&chip, chipClock);
|
||||
chip.rom_data = (unsigned char*)&chip.rom_mask;
|
||||
chip.rom_mask = 0;
|
||||
sampleMem=new unsigned char[getSampleMemCapacity()];
|
||||
sampleMemLen=0;
|
||||
chip.rom_data=sampleMem;
|
||||
chip.rom_mask=0xffffff;
|
||||
reset();
|
||||
|
||||
for (int i=0; i<19; i++) {
|
||||
|
|
@ -662,6 +707,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, unsigned in
|
|||
}
|
||||
|
||||
void DivPlatformQSound::quit() {
|
||||
delete[] sampleMem;
|
||||
for (int i=0; i<19; i++) {
|
||||
delete oscBuf[i];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ class DivPlatformQSound: public DivDispatch {
|
|||
int echoDelay;
|
||||
int echoFeedback;
|
||||
|
||||
unsigned char* sampleMem;
|
||||
size_t sampleMemLen;
|
||||
struct qsound_chip chip;
|
||||
unsigned short regPool[512];
|
||||
|
||||
|
|
@ -94,6 +96,10 @@ class DivPlatformQSound: public DivDispatch {
|
|||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
const char** getRegisterSheet();
|
||||
const char* getEffectName(unsigned char effect);
|
||||
const void* getSampleMem(int index = 0);
|
||||
size_t getSampleMemCapacity(int index = 0);
|
||||
size_t getSampleMemUsage(int index = 0);
|
||||
void renderSamples();
|
||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||
void quit();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "x1_010.h"
|
||||
#include "../engine.h"
|
||||
#include "../../ta-log.h"
|
||||
#include <math.h>
|
||||
|
||||
//#define rWrite(a,v) pendingWrites[a]=v;
|
||||
|
|
@ -909,6 +910,48 @@ void DivPlatformX1_010::poke(std::vector<DivRegWrite>& wlist) {
|
|||
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
|
||||
}
|
||||
|
||||
const void* DivPlatformX1_010::getSampleMem(int index) {
|
||||
return index == 0 ? sampleMem : 0;
|
||||
}
|
||||
|
||||
size_t DivPlatformX1_010::getSampleMemCapacity(int index) {
|
||||
return index == 0 ? 1048576 : 0;
|
||||
}
|
||||
|
||||
size_t DivPlatformX1_010::getSampleMemUsage(int index) {
|
||||
return index == 0 ? sampleMemLen : 0;
|
||||
}
|
||||
|
||||
void DivPlatformX1_010::renderSamples() {
|
||||
memset(sampleMem,0,getSampleMemCapacity());
|
||||
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int paddedLen=(s->length8+4095)&(~0xfff);
|
||||
// fit sample bank size to 128KB for Seta 2 external bankswitching logic (not emulated yet!)
|
||||
if (paddedLen>131072) {
|
||||
paddedLen=131072;
|
||||
}
|
||||
if ((memPos&0xfe0000)!=((memPos+paddedLen)&0xfe0000)) {
|
||||
memPos=(memPos+0x1ffff)&0xfe0000;
|
||||
}
|
||||
if (memPos>=getSampleMemCapacity()) {
|
||||
logW("out of X1-010 memory for sample %d!",i);
|
||||
break;
|
||||
}
|
||||
if (memPos+paddedLen>=getSampleMemCapacity()) {
|
||||
memcpy(sampleMem+memPos,s->data8,getSampleMemCapacity()-memPos);
|
||||
logW("out of X1-010 memory for sample %d!",i);
|
||||
} else {
|
||||
memcpy(sampleMem+memPos,s->data8,paddedLen);
|
||||
}
|
||||
s->offX1_010=memPos;
|
||||
memPos+=paddedLen;
|
||||
}
|
||||
sampleMemLen=memPos+256;
|
||||
}
|
||||
|
||||
int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
|
|
@ -919,7 +962,9 @@ int DivPlatformX1_010::init(DivEngine* p, int channels, int sugRate, unsigned in
|
|||
oscBuf[i]=new DivDispatchOscBuffer;
|
||||
}
|
||||
setFlags(flags);
|
||||
intf.parent=parent;
|
||||
sampleMem=new unsigned char[getSampleMemCapacity()];
|
||||
sampleMemLen=0;
|
||||
intf.memory=sampleMem;
|
||||
x1_010=new x1_010_core(intf);
|
||||
x1_010->reset();
|
||||
reset();
|
||||
|
|
@ -931,6 +976,7 @@ void DivPlatformX1_010::quit() {
|
|||
delete oscBuf[i];
|
||||
}
|
||||
delete x1_010;
|
||||
delete[] sampleMem;
|
||||
}
|
||||
|
||||
DivPlatformX1_010::~DivPlatformX1_010() {
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
class DivX1_010Interface: public x1_010_mem_intf {
|
||||
public:
|
||||
DivEngine* parent;
|
||||
unsigned char* memory;
|
||||
int sampleBank;
|
||||
virtual u8 read_byte(u32 address) override {
|
||||
if (parent->x1_010Mem==NULL) return 0;
|
||||
return parent->x1_010Mem[address & 0xfffff];
|
||||
if (memory==NULL) return 0;
|
||||
return memory[address & 0xfffff];
|
||||
}
|
||||
DivX1_010Interface(): parent(NULL), sampleBank(0) {}
|
||||
DivX1_010Interface(): memory(NULL), sampleBank(0) {}
|
||||
};
|
||||
|
||||
class DivPlatformX1_010: public DivDispatch {
|
||||
|
|
@ -115,6 +115,8 @@ class DivPlatformX1_010: public DivDispatch {
|
|||
DivDispatchOscBuffer* oscBuf[16];
|
||||
bool isMuted[16];
|
||||
bool stereo=false;
|
||||
unsigned char* sampleMem;
|
||||
size_t sampleMemLen;
|
||||
unsigned char sampleBank;
|
||||
DivX1_010Interface intf;
|
||||
x1_010_core* x1_010;
|
||||
|
|
@ -141,6 +143,10 @@ class DivPlatformX1_010: public DivDispatch {
|
|||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
const void* getSampleMem(int index = 0);
|
||||
size_t getSampleMemCapacity(int index = 0);
|
||||
size_t getSampleMemUsage(int index = 0);
|
||||
void renderSamples();
|
||||
const char** getRegisterSheet();
|
||||
const char* getEffectName(unsigned char effect);
|
||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "ym2610.h"
|
||||
#include "sound/ymfm/ymfm.h"
|
||||
#include "../engine.h"
|
||||
#include "../../ta-log.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
|
|
@ -245,6 +246,85 @@ const char* regCheatSheetYM2610[]={
|
|||
NULL
|
||||
};
|
||||
|
||||
const void* DivPlatformYM2610Base::getSampleMem(int index) {
|
||||
return index == 0 ? adpcmAMem : index == 1 ? adpcmBMem : NULL;
|
||||
}
|
||||
|
||||
size_t DivPlatformYM2610Base::getSampleMemCapacity(int index) {
|
||||
return index == 0 ? 16777216 : index == 1 ? 16777216 : 0;
|
||||
}
|
||||
|
||||
size_t DivPlatformYM2610Base::getSampleMemUsage(int index) {
|
||||
return index == 0 ? adpcmAMemLen : index == 1 ? adpcmBMemLen : 0;
|
||||
}
|
||||
|
||||
void DivPlatformYM2610Base::renderSamples() {
|
||||
memset(adpcmAMem,0,getSampleMemCapacity(0));
|
||||
|
||||
size_t memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int paddedLen=(s->lengthA+255)&(~0xff);
|
||||
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
|
||||
memPos=(memPos+0xfffff)&0xf00000;
|
||||
}
|
||||
if (memPos>=getSampleMemCapacity(0)) {
|
||||
logW("out of ADPCM-A memory for sample %d!",i);
|
||||
break;
|
||||
}
|
||||
if (memPos+paddedLen>=getSampleMemCapacity(0)) {
|
||||
memcpy(adpcmAMem+memPos,s->dataA,getSampleMemCapacity(0)-memPos);
|
||||
logW("out of ADPCM-A memory for sample %d!",i);
|
||||
} else {
|
||||
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
|
||||
}
|
||||
s->offA=memPos;
|
||||
memPos+=paddedLen;
|
||||
}
|
||||
adpcmAMemLen=memPos+256;
|
||||
|
||||
memset(adpcmBMem,0,getSampleMemCapacity(1));
|
||||
|
||||
memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int paddedLen=(s->lengthB+255)&(~0xff);
|
||||
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
|
||||
memPos=(memPos+0xfffff)&0xf00000;
|
||||
}
|
||||
if (memPos>=getSampleMemCapacity(1)) {
|
||||
logW("out of ADPCM-B memory for sample %d!",i);
|
||||
break;
|
||||
}
|
||||
if (memPos+paddedLen>=getSampleMemCapacity(1)) {
|
||||
memcpy(adpcmBMem+memPos,s->dataB,getSampleMemCapacity(1)-memPos);
|
||||
logW("out of ADPCM-B memory for sample %d!",i);
|
||||
} else {
|
||||
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
|
||||
}
|
||||
s->offB=memPos;
|
||||
memPos+=paddedLen;
|
||||
}
|
||||
adpcmBMemLen=memPos+256;
|
||||
}
|
||||
|
||||
int DivPlatformYM2610Base::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
adpcmAMem=new unsigned char[getSampleMemCapacity(0)];
|
||||
adpcmAMemLen=0;
|
||||
adpcmBMem=new unsigned char[getSampleMemCapacity(1)];
|
||||
adpcmBMemLen=0;
|
||||
iface.adpcmAMem=adpcmAMem;
|
||||
iface.adpcmBMem=adpcmBMem;
|
||||
iface.sampleBank=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DivPlatformYM2610Base::quit() {
|
||||
delete[] adpcmAMem;
|
||||
delete[] adpcmBMem;
|
||||
}
|
||||
|
||||
const char** DivPlatformYM2610::getRegisterSheet() {
|
||||
return regCheatSheetYM2610;
|
||||
}
|
||||
|
|
@ -1185,7 +1265,7 @@ void DivPlatformYM2610::setSkipRegisterWrites(bool value) {
|
|||
}
|
||||
|
||||
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
DivPlatformYM2610Base::init(p, channels, sugRate, flags);
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<14; i++) {
|
||||
|
|
@ -1197,8 +1277,6 @@ int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned in
|
|||
for (int i=0; i<14; i++) {
|
||||
oscBuf[i]->rate=rate;
|
||||
}
|
||||
iface.parent=parent;
|
||||
iface.sampleBank=0;
|
||||
fm=new ymfm::ym2610(iface);
|
||||
// YM2149, 2MHz
|
||||
ay=new DivPlatformAY8910;
|
||||
|
|
@ -1215,6 +1293,7 @@ void DivPlatformYM2610::quit() {
|
|||
ay->quit();
|
||||
delete ay;
|
||||
delete fm;
|
||||
DivPlatformYM2610Base::quit();
|
||||
}
|
||||
|
||||
DivPlatformYM2610::~DivPlatformYM2610() {
|
||||
|
|
|
|||
|
|
@ -27,14 +27,32 @@
|
|||
|
||||
class DivYM2610Interface: public ymfm::ymfm_interface {
|
||||
public:
|
||||
DivEngine* parent;
|
||||
unsigned char* adpcmAMem;
|
||||
unsigned char* adpcmBMem;
|
||||
int sampleBank;
|
||||
uint8_t ymfm_external_read(ymfm::access_class type, uint32_t address);
|
||||
void ymfm_external_write(ymfm::access_class type, uint32_t address, uint8_t data);
|
||||
DivYM2610Interface(): parent(NULL), sampleBank(0) {}
|
||||
DivYM2610Interface(): adpcmAMem(NULL), adpcmBMem(NULL), sampleBank(0) {}
|
||||
};
|
||||
|
||||
class DivPlatformYM2610: public DivDispatch {
|
||||
class DivPlatformYM2610Base: public DivDispatch {
|
||||
protected:
|
||||
unsigned char* adpcmAMem;
|
||||
size_t adpcmAMemLen;
|
||||
unsigned char* adpcmBMem;
|
||||
size_t adpcmBMemLen;
|
||||
DivYM2610Interface iface;
|
||||
|
||||
public:
|
||||
const void* getSampleMem(int index);
|
||||
size_t getSampleMemCapacity(int index);
|
||||
size_t getSampleMemUsage(int index);
|
||||
void renderSamples();
|
||||
int init(DivEngine* parent, int channels, int sugRate, unsigned int flags);
|
||||
void quit();
|
||||
};
|
||||
|
||||
class DivPlatformYM2610: public DivPlatformYM2610Base {
|
||||
protected:
|
||||
const unsigned short chanOffs[4]={
|
||||
0x01, 0x02, 0x101, 0x102
|
||||
|
|
@ -93,7 +111,6 @@ class DivPlatformYM2610: public DivDispatch {
|
|||
std::queue<QueuedWrite> writes;
|
||||
ymfm::ym2610* fm;
|
||||
ymfm::ym2610::output_data fmout;
|
||||
DivYM2610Interface iface;
|
||||
|
||||
DivPlatformAY8910* ay;
|
||||
unsigned char regPool[512];
|
||||
|
|
|
|||
|
|
@ -24,13 +24,11 @@
|
|||
uint8_t DivYM2610Interface::ymfm_external_read(ymfm::access_class type, uint32_t address) {
|
||||
switch (type) {
|
||||
case ymfm::ACCESS_ADPCM_A:
|
||||
if (parent->adpcmAMem==NULL) return 0;
|
||||
if ((address&0xffffff)>=parent->adpcmAMemLen) return 0;
|
||||
return parent->adpcmAMem[address&0xffffff];
|
||||
if (adpcmAMem==NULL) return 0;
|
||||
return adpcmAMem[address&0xffffff];
|
||||
case ymfm::ACCESS_ADPCM_B:
|
||||
if (parent->adpcmBMem==NULL) return 0;
|
||||
if ((address&0xffffff)>=parent->adpcmBMemLen) return 0;
|
||||
return parent->adpcmBMem[address&0xffffff];
|
||||
if (adpcmBMem==NULL) return 0;
|
||||
return adpcmBMem[address&0xffffff];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1243,7 +1243,7 @@ void DivPlatformYM2610B::setSkipRegisterWrites(bool value) {
|
|||
}
|
||||
|
||||
int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
DivPlatformYM2610Base::init(p, channels, sugRate, flags);
|
||||
dumpWrites=false;
|
||||
skipRegisterWrites=false;
|
||||
for (int i=0; i<16; i++) {
|
||||
|
|
@ -1255,8 +1255,6 @@ int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned i
|
|||
for (int i=0; i<16; i++) {
|
||||
oscBuf[i]->rate=rate;
|
||||
}
|
||||
iface.parent=parent;
|
||||
iface.sampleBank=0;
|
||||
fm=new ymfm::ym2610b(iface);
|
||||
// YM2149, 2MHz
|
||||
ay=new DivPlatformAY8910;
|
||||
|
|
@ -1273,6 +1271,7 @@ void DivPlatformYM2610B::quit() {
|
|||
ay->quit();
|
||||
delete ay;
|
||||
delete fm;
|
||||
DivPlatformYM2610Base::quit();
|
||||
}
|
||||
|
||||
DivPlatformYM2610B::~DivPlatformYM2610B() {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "ym2610.h"
|
||||
|
||||
class DivPlatformYM2610B: public DivDispatch {
|
||||
class DivPlatformYM2610B: public DivPlatformYM2610Base {
|
||||
protected:
|
||||
const unsigned short chanOffs[6]={
|
||||
0x00, 0x01, 0x02, 0x100, 0x101, 0x102
|
||||
|
|
@ -85,7 +85,6 @@ class DivPlatformYM2610B: public DivDispatch {
|
|||
std::queue<QueuedWrite> writes;
|
||||
ymfm::ym2610b* fm;
|
||||
ymfm::ym2610b::output_data fmout;
|
||||
DivYM2610Interface iface;
|
||||
unsigned char regPool[512];
|
||||
unsigned char lastBusy;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue