Merge branch 'tildearrow:master' into master
This commit is contained in:
commit
21d11c64b4
42 changed files with 294 additions and 75 deletions
|
|
@ -3246,6 +3246,10 @@ void DivEngine::setMetronomeVol(float vol) {
|
|||
metroVol=vol;
|
||||
}
|
||||
|
||||
void DivEngine::setSamplePreviewVol(float vol) {
|
||||
previewVol=vol;
|
||||
}
|
||||
|
||||
void DivEngine::setConsoleMode(bool enable) {
|
||||
consoleMode=enable;
|
||||
}
|
||||
|
|
@ -3450,6 +3454,7 @@ bool DivEngine::initAudioBackend() {
|
|||
clampSamples=getConfInt("clampSamples",0);
|
||||
lowLatency=getConfInt("lowLatency",0);
|
||||
metroVol=(float)(getConfInt("metroVol",100))/100.0f;
|
||||
previewVol=(float)(getConfInt("sampleVol",50))/100.0f;
|
||||
midiOutClock=getConfInt("midiOutClock",0);
|
||||
midiOutTime=getConfInt("midiOutTime",0);
|
||||
midiOutTimeRate=getConfInt("midiOutTimeRate",0);
|
||||
|
|
@ -3457,6 +3462,8 @@ bool DivEngine::initAudioBackend() {
|
|||
midiOutMode=getConfInt("midiOutMode",DIV_MIDI_MODE_NOTE);
|
||||
if (metroVol<0.0f) metroVol=0.0f;
|
||||
if (metroVol>2.0f) metroVol=2.0f;
|
||||
if (previewVol<0.0f) previewVol=0.0f;
|
||||
if (previewVol>1.0f) previewVol=1.0f;
|
||||
renderPoolThreads=getConfInt("renderPoolThreads",0);
|
||||
|
||||
if (lowLatency) logI("using low latency mode.");
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ class DivWorkPool;
|
|||
|
||||
#define DIV_UNSTABLE
|
||||
|
||||
#define DIV_VERSION "0.6pre13"
|
||||
#define DIV_ENGINE_VERSION 174
|
||||
#define DIV_VERSION "0.6pre14"
|
||||
#define DIV_ENGINE_VERSION 175
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
|
@ -490,6 +490,7 @@ class DivEngine {
|
|||
float metroFreq, metroPos;
|
||||
float metroAmp;
|
||||
float metroVol;
|
||||
float previewVol;
|
||||
|
||||
size_t totalProcessed;
|
||||
|
||||
|
|
@ -729,6 +730,9 @@ class DivEngine {
|
|||
int getSamplePreviewPos();
|
||||
double getSamplePreviewRate();
|
||||
|
||||
// set sample preview volume (1.0 = 100%)
|
||||
void setSamplePreviewVol(float vol);
|
||||
|
||||
// trigger sample preview
|
||||
void previewSample(int sample, int note=-1, int pStart=-1, int pEnd=-1);
|
||||
void stopSamplePreview();
|
||||
|
|
@ -1282,6 +1286,7 @@ class DivEngine {
|
|||
metroPos(0),
|
||||
metroAmp(0.0f),
|
||||
metroVol(1.0f),
|
||||
previewVol(1.0f),
|
||||
totalProcessed(0),
|
||||
renderPoolThreads(0),
|
||||
renderPool(NULL),
|
||||
|
|
|
|||
|
|
@ -152,11 +152,18 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
}
|
||||
if (is219) {
|
||||
if (chan[i].std.duty.had) {
|
||||
chan[i].noise=chan[i].std.duty.val&1;
|
||||
chan[i].invert=chan[i].std.duty.val&2;
|
||||
chan[i].surround=chan[i].std.duty.val&4;
|
||||
chan[i].freqChanged=true;
|
||||
chan[i].writeCtrl=true;
|
||||
unsigned char singleByte=(
|
||||
(chan[i].noise?1:0)|
|
||||
(chan[i].invert?2:0)|
|
||||
(chan[i].surround?4:0)
|
||||
);
|
||||
if (singleByte!=(chan[i].std.duty.val&7)) {
|
||||
chan[i].noise=chan[i].std.duty.val&1;
|
||||
chan[i].invert=chan[i].std.duty.val&2;
|
||||
chan[i].surround=chan[i].std.duty.val&4;
|
||||
chan[i].freqChanged=true;
|
||||
chan[i].writeCtrl=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chan[i].std.pitch.had) {
|
||||
|
|
@ -209,7 +216,7 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (is219) {
|
||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_C219)?1:0)|(chan[i].invert?0x40:0)|(chan[i].surround?8:0)|(chan[i].noise?4:0);
|
||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable() || chan[i].noise)?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_C219)?1:0)|(chan[i].invert?0x40:0)|(chan[i].surround?8:0)|(chan[i].noise?4:0);
|
||||
} else {
|
||||
ctrl|=(chan[i].active?0x80:0)|((s->isLoopable())?0x10:0)|((s->depth==DIV_SAMPLE_DEPTH_MULAW)?0x08:0);
|
||||
}
|
||||
|
|
@ -228,11 +235,15 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
start=sampleOff[chan[i].sample]&0xffff;
|
||||
end=MIN(start+s->length8-1,65535);
|
||||
}
|
||||
} else if (chan[i].noise && is219) {
|
||||
bank=groupBank[i>>2];
|
||||
start=0;
|
||||
end=1;
|
||||
}
|
||||
if (chan[i].audPos>0) {
|
||||
start=MIN(start+(MIN(chan[i].audPos,s->length8)>>1),65535);
|
||||
}
|
||||
if (s->isLoopable()) {
|
||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen && s->isLoopable()) {
|
||||
if (is219) {
|
||||
loop=MIN(start+(s->loopStart>>1),65535);
|
||||
end=MIN(start+(s->loopEnd>>1)-1,65535);
|
||||
|
|
@ -240,6 +251,8 @@ void DivPlatformC140::tick(bool sysTick) {
|
|||
loop=MIN(start+s->loopStart,65535);
|
||||
end=MIN(start+s->loopEnd-1,65535);
|
||||
}
|
||||
} else if (chan[i].noise && is219) {
|
||||
loop=0;
|
||||
}
|
||||
rWrite(0x05+(i<<4),0); // force keyoff first
|
||||
if (is219) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,16 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static const int msmRates[4]={
|
||||
4, 3, 2, 2
|
||||
};
|
||||
|
||||
int DivPlatformMSM6258::calcVGMRate() {
|
||||
int ret=chipClock/((clockSel+1)*512*msmRates[rateSel&3]);
|
||||
logD("MSM rate: %d",ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (--msmClockCount<0) {
|
||||
|
|
@ -93,6 +103,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
|||
if (rateSel!=(chan[i].std.duty.val&3)) {
|
||||
rateSel=chan[i].std.duty.val&3;
|
||||
rWrite(12,rateSel);
|
||||
updateSampleFreq=true;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.panL.had) {
|
||||
|
|
@ -105,6 +116,7 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
|||
if (clockSel!=(chan[i].std.ex1.val&1)) {
|
||||
clockSel=chan[i].std.ex1.val&1;
|
||||
rWrite(8,clockSel);
|
||||
updateSampleFreq=true;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.phaseReset.had) {
|
||||
|
|
@ -113,12 +125,23 @@ void DivPlatformMSM6258::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (updateSampleFreq) {
|
||||
int newRate=calcVGMRate();
|
||||
if (dumpWrites) addWrite(0xffff0001,newRate);
|
||||
updateSampleFreq=false;
|
||||
}
|
||||
if (chan[i].keyOn || chan[i].keyOff) {
|
||||
samplePos=0;
|
||||
rWrite(0,1); // turn off
|
||||
// turn off
|
||||
if (dumpWrites) addWrite(0xffff0002,0);
|
||||
rWrite(0,1);
|
||||
if (chan[i].active && !chan[i].keyOff) {
|
||||
if (sample>=0 && sample<parent->song.sampleLen) {
|
||||
// turn on
|
||||
rWrite(0,2);
|
||||
if (dumpWrites) addWrite(0xffff0000,sample);
|
||||
int newRate=calcVGMRate();
|
||||
if (dumpWrites) addWrite(0xffff0001,newRate);
|
||||
} else {
|
||||
sample=-1;
|
||||
}
|
||||
|
|
@ -220,10 +243,12 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
|||
case DIV_CMD_SAMPLE_FREQ:
|
||||
rateSel=c.value&3;
|
||||
rWrite(12,rateSel);
|
||||
updateSampleFreq=true;
|
||||
break;
|
||||
case DIV_CMD_SAMPLE_MODE:
|
||||
clockSel=c.value&1;
|
||||
rWrite(8,clockSel);
|
||||
updateSampleFreq=true;
|
||||
break;
|
||||
case DIV_CMD_PANNING: {
|
||||
if (c.value==0 && c.value2==0) {
|
||||
|
|
@ -317,8 +342,10 @@ void DivPlatformMSM6258::reset() {
|
|||
msmPan=3;
|
||||
rateSel=2;
|
||||
clockSel=0;
|
||||
updateSampleFreq=true;
|
||||
if (dumpWrites) {
|
||||
addWrite(0xffffffff,0);
|
||||
addWrite(0xffff0001,calcVGMRate());
|
||||
}
|
||||
for (int i=0; i<1; i++) {
|
||||
chan[i]=DivPlatformMSM6258::Channel();
|
||||
|
|
|
|||
|
|
@ -50,12 +50,15 @@ class DivPlatformMSM6258: public DivDispatch {
|
|||
|
||||
unsigned char sampleBank, msmPan, msmDivider, rateSel, msmClock, clockSel;
|
||||
signed char msmDividerCount, msmClockCount;
|
||||
bool updateSampleFreq;
|
||||
short msmOut;
|
||||
|
||||
int delay, updateOsc, sample, samplePos;
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
int calcVGMRate();
|
||||
|
||||
public:
|
||||
void acquire(short** buf, size_t len);
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ DivMacroInt* DivPlatformSoundUnit::getChanMacroInt(int ch) {
|
|||
}
|
||||
|
||||
unsigned short DivPlatformSoundUnit::getPan(int ch) {
|
||||
return parent->convertPanLinearToSplit(chan[ch].pan^0x80,8,255);
|
||||
return parent->convertPanLinearToSplit(chan[ch].pan+127,8,255);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivPlatformSoundUnit::getOscBuffer(int ch) {
|
||||
|
|
|
|||
|
|
@ -2205,7 +2205,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
} else if (srcPortSet==0xffd) {
|
||||
// sample preview
|
||||
for (size_t j=0; j<size; j++) {
|
||||
out[destSubPort][j]+=samp_bbOut[j]/32768.0;
|
||||
out[destSubPort][j]+=previewVol*(samp_bbOut[j]/32768.0);
|
||||
}
|
||||
} else if (srcPortSet==0xffe && playing && !halted) {
|
||||
// metronome
|
||||
|
|
|
|||
|
|
@ -1137,7 +1137,7 @@ void DivEngine::registerSystems() {
|
|||
|
||||
sysDefs[DIV_SYSTEM_PCSPKR]=new DivSysDef(
|
||||
"PC Speaker", NULL, 0x93, 0, 1, false, true, 0, false, 0,
|
||||
"good luck!",
|
||||
"good luck! you get one square and no volume control.",
|
||||
{"Square"},
|
||||
{"SQ"},
|
||||
{DIV_CH_PULSE},
|
||||
|
|
@ -1146,7 +1146,7 @@ void DivEngine::registerSystems() {
|
|||
|
||||
sysDefs[DIV_SYSTEM_PONG]=new DivSysDef(
|
||||
"Pong", NULL, 0xfc, 0, 1, false, true, 0, false, 0,
|
||||
"LOL",
|
||||
"please don't use this chip. it was added as a joke.",
|
||||
{"Square"},
|
||||
{"SQ"},
|
||||
{DIV_CH_PULSE},
|
||||
|
|
@ -1820,7 +1820,7 @@ void DivEngine::registerSystems() {
|
|||
|
||||
sysDefs[DIV_SYSTEM_GA20]=new DivSysDef(
|
||||
"Irem GA20", NULL, 0xc7, 0, 4, false, true, 0x171, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
|
||||
"yet another PCM chip from Irem.",
|
||||
"yet another PCM chip from Irem. like Amiga, but less pitch resolution and no sample loop.",
|
||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4"},
|
||||
{"CH1", "CH2", "CH3", "CH4"},
|
||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
@ -1890,7 +1890,7 @@ void DivEngine::registerSystems() {
|
|||
|
||||
sysDefs[DIV_SYSTEM_C140]=new DivSysDef(
|
||||
"Namco C140", NULL, 0xce, 0, 24, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_MULAW)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"Namco's first PCM chip from 1987.",
|
||||
"Namco's first PCM chip from 1987. it's pretty good for being so.",
|
||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"},
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"},
|
||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
@ -1901,7 +1901,7 @@ void DivEngine::registerSystems() {
|
|||
|
||||
sysDefs[DIV_SYSTEM_C219]=new DivSysDef(
|
||||
"Namco C219", NULL, 0xcf, 0, 16, false, true, 0x161, false, (1U<<DIV_SAMPLE_DEPTH_C219)|(1U<<DIV_SAMPLE_DEPTH_8BIT),
|
||||
"Namco's PCM chip used in their NA-1/2 hardware.",
|
||||
"Namco's PCM chip used in their NA-1/2 hardware.\nvery similar to C140, but has noise generator.",
|
||||
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16"},
|
||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16"},
|
||||
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
|
|
|
|||
|
|
@ -549,6 +549,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(8);
|
||||
w->writeC(0xff);
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6258:
|
||||
w->writeC(0xb8); // stop
|
||||
w->writeC(baseAddr2|0);
|
||||
w->writeC(1);
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6295:
|
||||
w->writeC(0xb8); // disable all channels
|
||||
w->writeC(baseAddr2|0);
|
||||
|
|
@ -1055,6 +1060,12 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(write.addr&0xff);
|
||||
w->writeC(write.val);
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6258:
|
||||
w->writeC(0xb7);
|
||||
w->writeC(baseAddr2|(write.addr&0x7f));
|
||||
w->writeC(write.val);
|
||||
logV("MSM write to %.2x %.2x",write.addr,write.val);
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6295:
|
||||
w->writeC(0xb8);
|
||||
w->writeC(baseAddr2|(write.addr&0x7f));
|
||||
|
|
@ -1238,6 +1249,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
bool writeDACSamples=false;
|
||||
bool writeNESSamples=false;
|
||||
bool writePCESamples=false;
|
||||
bool writeVOXSamples=false;
|
||||
DivDispatch* writeADPCM_OPNA[2]={NULL,NULL};
|
||||
DivDispatch* writeADPCM_OPNB[2]={NULL,NULL};
|
||||
DivDispatch* writeADPCM_Y8950[2]={NULL,NULL};
|
||||
|
|
@ -1746,6 +1758,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
writeRF5C68[0]=disCont[i].dispatch;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6258:
|
||||
if (!hasOKIM6258) {
|
||||
hasOKIM6258=disCont[i].dispatch->chipClock;
|
||||
CHIP_VOL(23,0.65);
|
||||
willExport[i]=true;
|
||||
writeVOXSamples=true;
|
||||
} else if (!(hasOKIM6258&0x40000000)) {
|
||||
isSecond[i]=true;
|
||||
CHIP_VOL_SECOND(23,0.65);
|
||||
willExport[i]=true;
|
||||
writeVOXSamples=true;
|
||||
hasOKIM6258|=0x40000000;
|
||||
howManyChips++;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6295:
|
||||
if (!hasOKIM6295) {
|
||||
hasOKIM6295=disCont[i].dispatch->chipClock;
|
||||
|
|
@ -1927,7 +1954,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
w->writeI(hasMultiPCM);
|
||||
w->writeI(hasuPD7759);
|
||||
w->writeI(hasOKIM6258);
|
||||
w->writeC(0); // flags
|
||||
w->writeC(hasOKIM6258?10:0); // flags
|
||||
w->writeC(0); // K flags
|
||||
w->writeC(c140Type); // C140 chip type
|
||||
w->writeC(0); // reserved
|
||||
|
|
@ -2066,6 +2093,18 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
}
|
||||
}
|
||||
|
||||
if (writeVOXSamples && !directStream) for (int i=0; i<song.sampleLen; i++) {
|
||||
DivSample* sample=song.sample[i];
|
||||
w->writeC(0x67);
|
||||
w->writeC(0x66);
|
||||
w->writeC(4);
|
||||
w->writeI(sample->lengthVOX);
|
||||
for (unsigned int j=0; j<sample->lengthVOX; j++) {
|
||||
unsigned char actualData=(sample->dataVOX[j]>>4)|(sample->dataVOX[j]<<4);
|
||||
w->writeC(actualData);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<2; i++) {
|
||||
// SegaPCM
|
||||
if (writeSegaPCM[i]!=NULL && writeSegaPCM[i]->getSampleMemUsage(0)>0) {
|
||||
|
|
@ -2344,6 +2383,20 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
w->writeI(24000); // default
|
||||
streamID++;
|
||||
break;
|
||||
case DIV_SYSTEM_MSM6258:
|
||||
w->writeC(0x90);
|
||||
w->writeC(streamID);
|
||||
w->writeC(isSecond[i]?0x97:0x17);
|
||||
w->writeC(0); // port
|
||||
w->writeC(1); // data input
|
||||
|
||||
w->writeC(0x91);
|
||||
w->writeC(streamID);
|
||||
w->writeC(4);
|
||||
w->writeC(1);
|
||||
w->writeC(0);
|
||||
streamID++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue