Merge remote-tracking branch 'upstream/master' into macro

# Conflicts:
#	src/engine/platform/c64.cpp
#	src/gui/insEdit.cpp
This commit is contained in:
cam900 2022-04-10 14:47:10 +09:00
commit ae4f005d67
41 changed files with 635 additions and 350 deletions

View file

@ -319,6 +319,18 @@ class DivDispatch {
*/
virtual int getPortaFloor(int ch);
/**
* get the required amplification level of this dispatch's output.
* @return the amplification level.
*/
virtual float getPostAmp();
/**
* check whether DC offset correction is required.
* @return truth.
*/
virtual bool getDCOffRequired();
/**
* get a description of a dispatch-specific effect.
* @param effect the effect.

View file

@ -79,6 +79,11 @@ void DivDispatchContainer::flush(size_t count) {
}
void DivDispatchContainer::fillBuf(size_t runtotal, size_t offset, size_t size) {
if (dcOffCompensation && runtotal>0) {
dcOffCompensation=false;
prevSample[0]=bbIn[0][0];
if (dispatch->isStereo()) prevSample[1]=bbIn[1][0];
}
if (lowQuality) {
for (size_t i=0; i<runtotal; i++) {
temp[0]=bbIn[0][i];
@ -126,6 +131,9 @@ void DivDispatchContainer::clear() {
temp[1]=0;
prevSample[0]=0;
prevSample[1]=0;
if (dispatch->getDCOffRequired()) {
dcOffCompensation=true;
}
// run for one cycle to determine DC offset
// TODO: SAA1099 doesn't like that
/*dispatch->acquire(bbIn[0],bbIn[1],0,1);

View file

@ -17,9 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dataErrors.h"
#include "song.h"
#include <functional>
#define _USE_MATH_DEFINES
#include "engine.h"
#include "instrument.h"
@ -873,6 +870,11 @@ void DivEngine::play() {
for (int i=0; i<DIV_MAX_CHANS; i++) {
keyHit[i]=false;
}
if (output) if (!skipping && output->midiOut!=NULL) {
int pos=totalTicksR/6;
output->midiOut->send(TAMidiMessage(TA_MIDI_POSITION,(pos>>7)&0x7f,pos&0x7f));
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_PLAY,0,0));
}
BUSY_END;
}
@ -918,6 +920,14 @@ void DivEngine::stop() {
for (int i=0; i<song.systemLen; i++) {
disCont[i].dispatch->notifyPlaybackStop();
}
if (output) if (output->midiOut!=NULL) {
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));
for (int i=0; i<chans; i++) {
if (chan[i].curMidiNote>=0) {
output->midiOut->send(TAMidiMessage(0x80|(i&15),chan[i].curMidiNote,0));
}
}
}
BUSY_END;
}

View file

@ -86,7 +86,8 @@ struct DivChannelState {
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit, resetArp;
int midiNote, curMidiNote;
int midiNote, curMidiNote, midiPitch;
bool midiAftertouch;
DivChannelState():
note(-1),
@ -130,7 +131,9 @@ struct DivChannelState {
noteOnInhibit(false),
resetArp(false),
midiNote(-1),
curMidiNote(-1) {}
curMidiNote(-1),
midiPitch(-1),
midiAftertouch(false) {}
};
struct DivNoteEvent {
@ -151,7 +154,7 @@ struct DivDispatchContainer {
int temp[2], prevSample[2];
short* bbIn[2];
short* bbOut[2];
bool lowQuality;
bool lowQuality, dcOffCompensation;
void setRates(double gotRate);
void setQuality(bool lowQual);
@ -169,7 +172,8 @@ struct DivDispatchContainer {
prevSample{0,0},
bbIn{NULL,NULL},
bbOut{NULL,NULL},
lowQuality(false) {}
lowQuality(false),
dcOffCompensation(false) {}
};
class DivEngine {
@ -295,6 +299,7 @@ class DivEngine {
bool keyHit[DIV_MAX_CHANS];
float* oscBuf[2];
float oscSize;
int oscReadPos, oscWritePos;
void runExportThread();
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
@ -769,6 +774,8 @@ class DivEngine {
totalProcessed(0),
oscBuf{NULL,NULL},
oscSize(1),
oscReadPos(0),
oscWritePos(0),
adpcmAMem(NULL),
adpcmAMemLen(0),
adpcmBMem(NULL),

View file

@ -17,7 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stddef.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include "filter.h"
@ -85,4 +84,4 @@ float* DivFilterTables::getSincIntegralTable() {
}
}
return sincIntegralTable;
}
}

View file

@ -567,12 +567,12 @@ void DivInstrument::putInsData(SafeWriter* w) {
w->writeC(ws.param4);
}
void readMacroData(DivInstrumentMacro &m, SafeReader& reader, short version) {
DivDataErrors DivInstrument::readMacroData(DivInstrumentMacro& m, SafeReader& reader, short version) {
char magic[4];
reader.read(magic,4);
if (memcmp(magic,"MACR",4)!=0) {
logE("invalid macro header!\n");
return /*DIV_DATA_INVALID_HEADER*/;
return DIV_DATA_INVALID_HEADER;
}
reader.readI();
@ -591,7 +591,7 @@ void readMacroData(DivInstrumentMacro &m, SafeReader& reader, short version) {
reader.readI(); // reserved
reader.readI(); // reserved
}
/*return DIV_DATA_SUCCESS*/;
return DIV_DATA_SUCCESS;
}
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
@ -695,65 +695,173 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
for (int k=0; k<14; k++) reader.readC();
if (istest) {
readMacroData(std.volMacro,reader,version);
readMacroData(std.arpMacro,reader,version);
readMacroData(std.dutyMacro,reader,version);
readMacroData(std.waveMacro,reader,version);
readMacroData(std.pitchMacro,reader,version);
readMacroData(std.ex1Macro,reader,version);
readMacroData(std.ex2Macro,reader,version);
readMacroData(std.ex3Macro,reader,version);
readMacroData(std.algMacro,reader,version);
readMacroData(std.fbMacro,reader,version);
readMacroData(std.fmsMacro,reader,version);
readMacroData(std.fms2Macro,reader,version);
readMacroData(std.amsMacro,reader,version);
readMacroData(std.ams2Macro,reader,version);
readMacroData(std.panLMacro,reader,version);
readMacroData(std.panRMacro,reader,version);
readMacroData(std.phaseResetMacro,reader,version);
readMacroData(std.ex4Macro,reader,version);
readMacroData(std.ex5Macro,reader,version);
readMacroData(std.ex6Macro,reader,version);
readMacroData(std.ex7Macro,reader,version);
readMacroData(std.ex8Macro,reader,version);
if (readMacroData(std.volMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.arpMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.dutyMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.waveMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.pitchMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex1Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex3Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.algMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.fbMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.fmsMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.fms2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.amsMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ams2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.panLMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.panRMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.phaseResetMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex4Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex5Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex6Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex7Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ex8Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
// FM macros
for (int i=0; i<4; i++) {
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
readMacroData(op.amMacro,reader,version);
readMacroData(op.arMacro,reader,version);
readMacroData(op.drMacro,reader,version);
readMacroData(op.multMacro,reader,version);
readMacroData(op.rrMacro,reader,version);
readMacroData(op.slMacro,reader,version);
readMacroData(op.tlMacro,reader,version);
readMacroData(op.dt2Macro,reader,version);
readMacroData(op.rsMacro,reader,version);
readMacroData(op.dtMacro,reader,version);
readMacroData(op.d2rMacro,reader,version);
readMacroData(op.ssgMacro,reader,version);
readMacroData(op.damMacro,reader,version);
readMacroData(op.dvbMacro,reader,version);
readMacroData(op.egtMacro,reader,version);
readMacroData(op.kslMacro,reader,version);
readMacroData(op.susMacro,reader,version);
readMacroData(op.vibMacro,reader,version);
readMacroData(op.wsMacro,reader,version);
readMacroData(op.ksrMacro,reader,version);
if (readMacroData(op.amMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.arMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.drMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.multMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.rrMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.slMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.tlMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.dt2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.rsMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.dtMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.d2rMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.ssgMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.damMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.dvbMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.egtMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.kslMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.susMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.vibMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.wsMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(op.ksrMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
}
// wavesynth macros
readMacroData(std.ws.wave1Macro,reader,version);
readMacroData(std.ws.wave2Macro,reader,version);
readMacroData(std.ws.rateDividerMacro,reader,version);
readMacroData(std.ws.effectMacro,reader,version);
readMacroData(std.ws.oneShotMacro,reader,version);
readMacroData(std.ws.enabledMacro,reader,version);
readMacroData(std.ws.globalMacro,reader,version);
readMacroData(std.ws.speedMacro,reader,version);
readMacroData(std.ws.param1Macro,reader,version);
readMacroData(std.ws.param2Macro,reader,version);
readMacroData(std.ws.param3Macro,reader,version);
readMacroData(std.ws.param4Macro,reader,version);
if (readMacroData(std.ws.wave1Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.wave2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.rateDividerMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.effectMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.oneShotMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.enabledMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.globalMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.speedMacro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.param1Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.param2Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.param3Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
if (readMacroData(std.ws.param4Macro,reader,version)!=DIV_DATA_SUCCESS) {
return DIV_DATA_INVALID_HEADER;
}
}
if (!istest) {
// standard
@ -882,18 +990,42 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
for (int i=0; i<4; i++) {
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
reader.readByte(op.amMacro.val,op.amMacro.len,1);
reader.readByte(op.arMacro.val,op.arMacro.len,1);
reader.readByte(op.drMacro.val,op.drMacro.len,1);
reader.readByte(op.multMacro.val,op.multMacro.len,1);
reader.readByte(op.rrMacro.val,op.rrMacro.len,1);
reader.readByte(op.slMacro.val,op.slMacro.len,1);
reader.readByte(op.tlMacro.val,op.tlMacro.len,1);
reader.readByte(op.dt2Macro.val,op.dt2Macro.len,1);
reader.readByte(op.rsMacro.val,op.rsMacro.len,1);
reader.readByte(op.dtMacro.val,op.dtMacro.len,1);
reader.readByte(op.d2rMacro.val,op.d2rMacro.len,1);
reader.readByte(op.ssgMacro.val,op.ssgMacro.len,1);
for (int l=0; l<op.amMacro.len; l++) {
op.amMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.arMacro.len; l++) {
op.arMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.drMacro.len; l++) {
op.drMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.multMacro.len; l++) {
op.multMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.rrMacro.len; l++) {
op.rrMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.slMacro.len; l++) {
op.slMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.tlMacro.len; l++) {
op.tlMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.dt2Macro.len; l++) {
op.dt2Macro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.rsMacro.len; l++) {
op.rsMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.dtMacro.len; l++) {
op.dtMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.d2rMacro.len; l++) {
op.d2rMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.ssgMacro.len; l++) {
op.ssgMacro.val[l]=(unsigned char)reader.readC();
}
}
}
@ -974,14 +1106,30 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
for (int i=0; i<4; i++) {
DivInstrumentSTD::OpMacro& op=std.opMacros[i];
reader.readByte(op.damMacro.val,op.damMacro.len,1);
reader.readByte(op.dvbMacro.val,op.dvbMacro.len,1);
reader.readByte(op.egtMacro.val,op.egtMacro.len,1);
reader.readByte(op.kslMacro.val,op.kslMacro.len,1);
reader.readByte(op.susMacro.val,op.susMacro.len,1);
reader.readByte(op.vibMacro.val,op.vibMacro.len,1);
reader.readByte(op.wsMacro.val,op.wsMacro.len,1);
reader.readByte(op.ksrMacro.val,op.ksrMacro.len,1);
for (int l=0; l<op.damMacro.len; l++) {
op.damMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.dvbMacro.len; l++) {
op.dvbMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.egtMacro.len; l++) {
op.egtMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.kslMacro.len; l++) {
op.kslMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.susMacro.len; l++) {
op.susMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.vibMacro.len; l++) {
op.vibMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.wsMacro.len; l++) {
op.wsMacro.val[l]=(unsigned char)reader.readC();
}
for (int l=0; l<op.ksrMacro.len; l++) {
op.ksrMacro.val[l]=(unsigned char)reader.readC();
}
}
}
}

View file

@ -437,7 +437,7 @@ struct DivInstrument {
* @param version the format version.
* @return a DivDataErrors.
*/
void readMacroData(DivInstrumentMacro& m, SafeReader& reader, short version);
DivDataErrors readMacroData(DivInstrumentMacro& m, SafeReader& reader, short version);
/**
* save this instrument to a file.

View file

@ -62,134 +62,84 @@ void DivMacroInt::release() {
void DivMacroInt::init(DivInstrument* which) {
ins=which;
macroList.clear();
// initialize common macros
vol.init();
arp.init();
duty.init();
wave.init();
pitch.init();
ex1.init();
ex2.init();
ex3.init();
alg.init();
fb.init();
fms.init();
ams.init();
fms2.init();
ams2.init();
panL.init();
panR.init();
phaseReset.init();
ex4.init();
ex5.init();
ex6.init();
ex7.init();
ex8.init();
// initialize
while (!macroList.empty()) {
macroList.front().init();
macroList.pop_front();
}
released=false;
// initialize FM operator macro
op[0]=IntOp();
op[1]=IntOp();
op[2]=IntOp();
op[3]=IntOp();
// initialize wavesynth macro
ws=IntWS();
if (ins==NULL) return;
// prepare common macro
if (ins->std.volMacro.len>0) {
macroList.push_back(DivMacroExecList(vol,ins->std.volMacro));
vol.prepare(&ins->std.volMacro);
}
if (ins->std.arpMacro.len>0) {
macroList.push_back(DivMacroExecList(arp,ins->std.arpMacro));
arp.prepare(&ins->std.arpMacro);
}
if (ins->std.dutyMacro.len>0) {
macroList.push_back(DivMacroExecList(duty,ins->std.dutyMacro));
duty.prepare(&ins->std.dutyMacro);
}
if (ins->std.waveMacro.len>0) {
macroList.push_back(DivMacroExecList(wave,ins->std.waveMacro));
wave.prepare(&ins->std.waveMacro);
}
if (ins->std.pitchMacro.len>0) {
macroList.push_back(DivMacroExecList(pitch,ins->std.pitchMacro));
pitch.prepare(&ins->std.pitchMacro);
}
if (ins->std.ex1Macro.len>0) {
macroList.push_back(DivMacroExecList(ex1,ins->std.ex1Macro));
ex1.prepare(&ins->std.ex1Macro);
}
if (ins->std.ex2Macro.len>0) {
macroList.push_back(DivMacroExecList(ex2,ins->std.ex2Macro));
ex2.prepare(&ins->std.ex2Macro);
}
if (ins->std.ex3Macro.len>0) {
macroList.push_back(DivMacroExecList(ex3,ins->std.ex3Macro));
ex3.prepare(&ins->std.ex3Macro);
}
if (ins->std.algMacro.len>0) {
macroList.push_back(DivMacroExecList(alg,ins->std.algMacro));
alg.prepare(&ins->std.algMacro);
}
if (ins->std.fbMacro.len>0) {
macroList.push_back(DivMacroExecList(fb,ins->std.fbMacro));
fb.prepare(&ins->std.fbMacro);
}
if (ins->std.fmsMacro.len>0) {
macroList.push_back(DivMacroExecList(fms,ins->std.fmsMacro));
fms.prepare(&ins->std.fmsMacro);
}
if (ins->std.fms2Macro.len>0) {
macroList.push_back(DivMacroExecList(fms2,ins->std.fms2Macro));
fms2.prepare(&ins->std.fms2Macro);
}
if (ins->std.amsMacro.len>0) {
macroList.push_back(DivMacroExecList(ams,ins->std.amsMacro));
ams.prepare(&ins->std.amsMacro);
}
if (ins->std.ams2Macro.len>0) {
macroList.push_back(DivMacroExecList(ams2,ins->std.ams2Macro));
ams2.prepare(&ins->std.ams2Macro);
}
// TODO: other macros
if (ins->std.panLMacro.len>0) {
macroList.push_back(DivMacroExecList(panL,ins->std.panLMacro));
panL.prepare(&ins->std.panLMacro);
}
if (ins->std.panRMacro.len>0) {
macroList.push_back(DivMacroExecList(panR,ins->std.panRMacro));
panR.prepare(&ins->std.panRMacro);
}
if (ins->std.phaseResetMacro.len>0) {
macroList.push_back(DivMacroExecList(phaseReset,ins->std.phaseResetMacro));
phaseReset.prepare(&ins->std.phaseResetMacro);
}
if (ins->std.ex4Macro.len>0) {
macroList.push_back(DivMacroExecList(ex4,ins->std.ex4Macro));
ex4.prepare(&ins->std.ex4Macro);
}
if (ins->std.ex5Macro.len>0) {
macroList.push_back(DivMacroExecList(ex5,ins->std.ex5Macro));
ex5.prepare(&ins->std.ex5Macro);
}
if (ins->std.ex6Macro.len>0) {
macroList.push_back(DivMacroExecList(ex6,ins->std.ex6Macro));
ex6.prepare(&ins->std.ex6Macro);
}
if (ins->std.ex7Macro.len>0) {
macroList.push_back(DivMacroExecList(ex7,ins->std.ex7Macro));
ex7.prepare(&ins->std.ex7Macro);
}
if (ins->std.ex8Macro.len>0) {
macroList.push_back(DivMacroExecList(ex8,ins->std.ex8Macro));
ex8.prepare(&ins->std.ex8Macro);
}
// prepare FM operator macros
@ -198,135 +148,103 @@ void DivMacroInt::init(DivInstrument* which) {
IntOp& o=op[i];
if (m.amMacro.len>0) {
macroList.push_back(DivMacroExecList(o.am,m.amMacro));
o.am.prepare(&m.amMacro);
}
if (m.arMacro.len>0) {
macroList.push_back(DivMacroExecList(o.ar,m.arMacro));
o.ar.prepare(&m.arMacro);
}
if (m.drMacro.len>0) {
macroList.push_back(DivMacroExecList(o.dr,m.drMacro));
o.dr.prepare(&m.drMacro);
}
if (m.multMacro.len>0) {
macroList.push_back(DivMacroExecList(o.mult,m.multMacro));
o.mult.prepare(&m.multMacro);
}
if (m.rrMacro.len>0) {
macroList.push_back(DivMacroExecList(o.rr,m.rrMacro));
o.rr.prepare(&m.rrMacro);
}
if (m.slMacro.len>0) {
macroList.push_back(DivMacroExecList(o.sl,m.slMacro));
o.sl.prepare(&m.slMacro);
}
if (m.tlMacro.len>0) {
macroList.push_back(DivMacroExecList(o.tl,m.tlMacro));
o.tl.prepare(&m.tlMacro);
}
if (m.dt2Macro.len>0) {
macroList.push_back(DivMacroExecList(o.dt2,m.dt2Macro));
o.dt2.prepare(&m.dt2Macro);
}
if (m.rsMacro.len>0) {
macroList.push_back(DivMacroExecList(o.rs,m.rsMacro));
o.rs.prepare(&m.rsMacro);
}
if (m.dtMacro.len>0) {
macroList.push_back(DivMacroExecList(o.dt,m.dtMacro));
o.dt.prepare(&m.dtMacro);
}
if (m.d2rMacro.len>0) {
macroList.push_back(DivMacroExecList(o.d2r,m.d2rMacro));
o.d2r.prepare(&m.d2rMacro);
}
if (m.ssgMacro.len>0) {
macroList.push_back(DivMacroExecList(o.ssg,m.ssgMacro));
o.ssg.prepare(&m.ssgMacro);
}
if (m.damMacro.len>0) {
macroList.push_back(DivMacroExecList(o.dam,m.damMacro));
o.dam.prepare(&m.damMacro);
}
if (m.dvbMacro.len>0) {
macroList.push_back(DivMacroExecList(o.dvb,m.dvbMacro));
o.dvb.prepare(&m.dvbMacro);
}
if (m.egtMacro.len>0) {
macroList.push_back(DivMacroExecList(o.egt,m.egtMacro));
o.egt.prepare(&m.egtMacro);
}
if (m.kslMacro.len>0) {
macroList.push_back(DivMacroExecList(o.ksl,m.kslMacro));
o.ksl.prepare(&m.kslMacro);
}
if (m.susMacro.len>0) {
macroList.push_back(DivMacroExecList(o.sus,m.susMacro));
o.sus.prepare(&m.susMacro);
}
if (m.vibMacro.len>0) {
macroList.push_back(DivMacroExecList(o.vib,m.vibMacro));
o.vib.prepare(&m.vibMacro);
}
if (m.wsMacro.len>0) {
macroList.push_back(DivMacroExecList(o.ws,m.wsMacro));
o.ws.prepare(&m.wsMacro);
}
if (m.ksrMacro.len>0) {
macroList.push_back(DivMacroExecList(o.ksr,m.ksrMacro));
o.ksr.prepare(&m.ksrMacro);
}
}
// prepare wavesynth macros
if (ins->std.ws.wave1Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.wave1,ins->std.ws.wave1Macro));
ws.wave1.prepare(&ins->std.ws.wave1Macro);
}
if (ins->std.ws.wave2Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.wave2,ins->std.ws.wave2Macro));
ws.wave2.prepare(&ins->std.ws.wave2Macro);
}
if (ins->std.ws.rateDividerMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.rateDivider,ins->std.ws.rateDividerMacro));
ws.rateDivider.prepare(&ins->std.ws.rateDividerMacro);
}
if (ins->std.ws.effectMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.effect,ins->std.ws.effectMacro));
ws.effect.prepare(&ins->std.ws.effectMacro);
}
if (ins->std.ws.oneShotMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.oneShot,ins->std.ws.oneShotMacro));
ws.oneShot.prepare(&ins->std.ws.oneShotMacro);
}
if (ins->std.ws.enabledMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.enabled,ins->std.ws.enabledMacro));
ws.enabled.prepare(&ins->std.ws.enabledMacro);
}
if (ins->std.ws.globalMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.global,ins->std.ws.globalMacro));
ws.global.prepare(&ins->std.ws.globalMacro);
}
if (ins->std.ws.speedMacro.len>0) {
macroList.push_back(DivMacroExecList(ws.speed,ins->std.ws.speedMacro));
ws.speed.prepare(&ins->std.ws.speedMacro);
}
if (ins->std.ws.param1Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.param1,ins->std.ws.param1Macro));
ws.param1.prepare(&ins->std.ws.param1Macro);
}
if (ins->std.ws.param2Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.param2,ins->std.ws.param2Macro));
ws.param2.prepare(&ins->std.ws.param2Macro);
}
if (ins->std.ws.param3Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.param3,ins->std.ws.param3Macro));
ws.param3.prepare(&ins->std.ws.param3Macro);
}
if (ins->std.ws.param4Macro.len>0) {
macroList.push_back(DivMacroExecList(ws.param4,ins->std.ws.param4Macro));
ws.param4.prepare(&ins->std.ws.param4Macro);
}
if (!macroList.empty()) {
for (std::list<DivMacroExecList>::iterator iter = macroList.begin(); iter!= macroList.end(); iter++) {

View file

@ -24,26 +24,20 @@
#include <list>
struct DivMacroStruct {
DivInstrumentMacro* source;
int pos;
int val;
bool has, had, finished, will;
unsigned int mode;
void doMacro(DivInstrumentMacro& source, bool released);
void init() {
source=NULL;
pos=mode=0;
has=had=will=false;
}
void prepare(DivInstrumentMacro* s) {
if (s!=NULL) {
source=s;
has=had=will=true;
mode=source->mode;
}
void prepare(DivInstrumentMacro& source) {
has=had=will=true;
mode=source.mode;
}
DivMacroStruct():
source(NULL),
pos(0),
val(0),
has(false),
@ -56,8 +50,11 @@ struct DivMacroStruct {
struct DivMacroExecList {
DivMacroStruct& macro;
DivInstrumentMacro& source;
void init() {
macro.init();
}
void prepare() {
macro.prepare(&source);
macro.prepare(source);
}
void doMacro(bool released) {
macro.doMacro(source, released);
@ -155,6 +152,7 @@ class DivMacroInt {
DivMacroInt():
ins(NULL),
macroList(),
released(false),
vol(),
arp(),

View file

@ -74,6 +74,14 @@ int DivDispatch::getPortaFloor(int ch) {
return 0x00;
}
float DivDispatch::getPostAmp() {
return 1.0f;
}
bool DivDispatch::getDCOffRequired() {
return false;
}
const char* DivDispatch::getEffectName(unsigned char effect) {
return NULL;
}

View file

@ -497,6 +497,10 @@ void DivPlatformAY8910::flushWrites() {
while (!writes.empty()) writes.pop();
}
bool DivPlatformAY8910::getDCOffRequired() {
return true;
}
void DivPlatformAY8910::reset() {
while (!writes.empty()) writes.pop();
ay->device_reset();

View file

@ -95,6 +95,7 @@ class DivPlatformAY8910: public DivDispatch {
void setFlags(unsigned int flags);
bool isStereo();
bool keyOffAffectsArp(int ch);
bool getDCOffRequired();
void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist);

View file

@ -123,7 +123,7 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l
}
while (!writes.empty()) {
QueuedWrite w=writes.front();
if (bank!=(w.addr>>4)) {
if ((int)bank!=(w.addr>>4)) {
bank=w.addr>>4;
ay->address_w(0x0d);
ay->data_w(0xa0|(bank<<4)|ayEnvMode[0]);

View file

@ -118,7 +118,7 @@ void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len)
void DivPlatformC64::updateFilter() {
rWrite(0x15,filtCut&7);
rWrite(0x16,filtCut>>3);
rWrite(0x17,(filtRes<<4)|(chan[2].filter<<2)|(chan[1].filter<<1)|(chan[0].filter));
rWrite(0x17,(filtRes<<4)|(chan[2].filter<<2)|(chan[1].filter<<1)|(int)(chan[0].filter));
rWrite(0x18,(filtControl<<4)|vol);
}
@ -177,7 +177,7 @@ void DivPlatformC64::tick() {
}
if (chan[i].std.wave.had) {
chan[i].wave=chan[i].std.wave.val;
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|chan[i].active);
rWrite(i*7+4,(isMuted[i]?8:(chan[i].wave<<4))|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
}
if (chan[i].std.ex1.had) {
filtControl=chan[i].std.ex1.val&15;
@ -232,7 +232,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
rWrite(c.chan*7+3,chan[c.chan].duty>>8);
}
if (chan[c.chan].insChanged) {
chan[c.chan].wave=(ins->c64.noiseOn<<3)|(ins->c64.pulseOn<<2)|(ins->c64.sawOn<<1)|(ins->c64.triOn);
chan[c.chan].wave=(ins->c64.noiseOn<<3)|(ins->c64.pulseOn<<2)|(ins->c64.sawOn<<1)|(int)(ins->c64.triOn);
chan[c.chan].attack=ins->c64.a;
chan[c.chan].decay=(ins->c64.s==15)?0:ins->c64.d;
chan[c.chan].sustain=ins->c64.s;
@ -245,7 +245,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
if (ins->c64.initFilter) {
filtCut=ins->c64.cut;
filtRes=ins->c64.res;
filtControl=ins->c64.lp|(ins->c64.bp<<1)|(ins->c64.hp<<2)|(ins->c64.ch3off<<3);
filtControl=(int)(ins->c64.lp)|(ins->c64.bp<<1)|(ins->c64.hp<<2)|(ins->c64.ch3off<<3);
}
updateFilter();
}
@ -330,7 +330,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
break;
case DIV_CMD_WAVE:
chan[c.chan].wave=c.value;
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case DIV_CMD_LEGATO:
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0)));
@ -411,11 +411,11 @@ int DivPlatformC64::dispatch(DivCommand c) {
break;
case 4:
chan[c.chan].ring=c.value;
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case 5:
chan[c.chan].sync=c.value;
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|chan[c.chan].active);
rWrite(c.chan*7+4,(isMuted[c.chan]?8:(chan[c.chan].wave<<4))|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active));
break;
case 6:
filtControl&=7;
@ -434,7 +434,7 @@ int DivPlatformC64::dispatch(DivCommand c) {
void DivPlatformC64::muteChannel(int ch, bool mute) {
isMuted[ch]=mute;
rWrite(ch*7+4,(isMuted[ch]?8:(chan[ch].wave<<4))|(chan[ch].ring<<2)|(chan[ch].sync<<1)|chan[ch].active);
rWrite(ch*7+4,(isMuted[ch]?8:(chan[ch].wave<<4))|(chan[ch].ring<<2)|(chan[ch].sync<<1)|(int)(chan[ch].active));
}
void DivPlatformC64::forceIns() {

View file

@ -89,7 +89,6 @@ void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len
if (!isMuted[2]) {
sample+=mmc5->pcm.output*2;
}
sample=(sample-128)<<6;
if (sample>32767) sample=32767;
if (sample<-32768) sample=-32768;
bufL[i]=sample;
@ -336,6 +335,10 @@ int DivPlatformMMC5::getRegisterPoolSize() {
return 32;
}
float DivPlatformMMC5::getPostAmp() {
return 64.0f;
}
void DivPlatformMMC5::reset() {
for (int i=0; i<3; i++) {
chan[i]=DivPlatformMMC5::Channel();

View file

@ -74,6 +74,7 @@ class DivPlatformMMC5: public DivDispatch {
void tick();
void muteChannel(int ch, bool mute);
bool keyOffAffectsArp(int ch);
float getPostAmp();
void setFlags(unsigned int flags);
void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val);

View file

@ -80,7 +80,14 @@ void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len)
DivSample* s=parent->getSample(dacSample);
if (s->samples>0) {
if (!isMuted[4]) {
rWrite(0x4011,((unsigned char)s->data8[dacPos]+0x80)>>1);
unsigned char next=((unsigned char)s->data8[dacPos]+0x80)>>1;
if (dacAntiClickOn && dacAntiClick<next) {
dacAntiClick+=8;
rWrite(0x4011,dacAntiClick);
} else {
dacAntiClickOn=false;
rWrite(0x4011,next);
}
}
if (++dacPos>=s->samples) {
if (s->loopStart>=0 && s->loopStart<(int)s->samples) {
@ -101,7 +108,7 @@ void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len)
if (nes->apu.clocked) {
nes->apu.clocked=false;
}
int sample=(pulse_output(nes)+tnd_output(nes)-128)<<7;
int sample=(pulse_output(nes)+tnd_output(nes));
if (sample>32767) sample=32767;
if (sample<-32768) sample=-32768;
bufL[i]=sample;
@ -454,6 +461,10 @@ int DivPlatformNES::getRegisterPoolSize() {
return 32;
}
float DivPlatformNES::getPostAmp() {
return 128.0f;
}
void DivPlatformNES::reset() {
for (int i=0; i<5; i++) {
chan[i]=DivPlatformNES::Channel();
@ -476,6 +487,9 @@ void DivPlatformNES::reset() {
rWrite(0x4015,0x1f);
rWrite(0x4001,chan[0].sweep);
rWrite(0x4005,chan[1].sweep);
dacAntiClickOn=true;
dacAntiClick=0;
}
bool DivPlatformNES::keyOffAffectsArp(int ch) {

View file

@ -54,10 +54,11 @@ class DivPlatformNES: public DivDispatch {
Channel chan[5];
bool isMuted[5];
int dacPeriod, dacRate;
unsigned int dacPos;
unsigned int dacPos, dacAntiClick;
int dacSample;
unsigned char sampleBank;
unsigned char apuType;
bool dacAntiClickOn;
struct NESAPU* nes;
unsigned char regPool[128];
@ -74,6 +75,7 @@ class DivPlatformNES: public DivDispatch {
void tick();
void muteChannel(int ch, bool mute);
bool keyOffAffectsArp(int ch);
float getPostAmp();
void setFlags(unsigned int flags);
void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val);

View file

@ -371,7 +371,7 @@ void DivPlatformOPL::tick() {
if (update4OpMask) {
update4OpMask=false;
if (oplType==3) {
unsigned char opMask=chan[0].fourOp|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5);
unsigned char opMask=(int)(chan[0].fourOp)|(chan[2].fourOp<<1)|(chan[4].fourOp<<2)|(chan[6].fourOp<<3)|(chan[8].fourOp<<4)|(chan[10].fourOp<<5);
immWrite(0x104,opMask);
//printf("updating opMask to %.2x\n",opMask);
}

View file

@ -620,7 +620,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
}
case DIV_CMD_FM_EXTCH:
if (!properDrumsSys) break;
if (properDrums==c.value) break;
if ((int)properDrums==c.value) break;
if (c.value) {
properDrums=true;
immWrite(0x0e,0x20);

View file

@ -414,6 +414,16 @@ void DivPlatformSAA1099::reset() {
extMode=false;
rWrite(8,255);
rWrite(9,255);
rWrite(10,255);
rWrite(11,255);
rWrite(12,255);
rWrite(13,255);
rWrite(16,0x77);
rWrite(17,0x77);
rWrite(18,0x77);
rWrite(0x1c,2);
rWrite(0x1c,1);
}

View file

@ -1120,7 +1120,7 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
for (int chan = 0; chan < NUM_CHANNELS; chan++)
{
tone = &m_tone[chan];
m_vol_enabled[chan] = (tone->output | tone_enable(chan)) & (noise_output() | noise_enable(chan));
m_vol_enabled[chan] = (tone->output | (unsigned char)tone_enable(chan)) & (noise_output() | (unsigned char)noise_enable(chan));
}
/* update envelope */

View file

@ -213,7 +213,8 @@ void apu_turn_on(struct NESAPU* a, BYTE apu_type) {
a->S2.sweep.delay = 1;
a->S2.sweep.divider = 1;
a->TR.frequency = 1;
a->TR.sequencer = 0;
/* questo era 0 ma produce click nell'audio */
a->TR.sequencer = 7;
a->NS.frequency = 1;
a->NS.shift = 1;
a->DMC.frequency = 1;

View file

@ -33,7 +33,7 @@
#pragma once
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif

View file

@ -17,9 +17,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "blip_buf.h"
#include "song.h"
#include "wavetable.h"
#define _USE_MATH_DEFINES
#include "dispatch.h"
#include "engine.h"
@ -201,16 +198,24 @@ int DivEngine::dispatchCmd(DivCommand c) {
chan[c.chan].curMidiNote=-1;
break;
case DIV_CMD_INSTRUMENT:
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
if (chan[c.chan].lastIns!=c.value) {
output->midiOut->send(TAMidiMessage(0xc0|(c.chan&15),c.value,0));
}
break;
case DIV_CMD_VOLUME:
//output->midiOut->send(TAMidiMessage(0xb0|(c.chan&15),0x07,scaledVol));
if (chan[c.chan].curMidiNote>=0 && chan[c.chan].midiAftertouch) {
chan[c.chan].midiAftertouch=false;
output->midiOut->send(TAMidiMessage(0xa0|(c.chan&15),chan[c.chan].curMidiNote,scaledVol));
}
break;
case DIV_CMD_PITCH: {
int pitchBend=8192+(c.value<<5);
if (pitchBend<0) pitchBend=0;
if (pitchBend>16383) pitchBend=16383;
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
if (pitchBend!=chan[c.chan].midiPitch) {
chan[c.chan].midiPitch=pitchBend;
output->midiOut->send(TAMidiMessage(0xe0|(c.chan&15),pitchBend&0x7f,pitchBend>>7));
}
break;
}
default:
@ -963,6 +968,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
// volume
if (pat->data[whatRow][3]!=-1) {
if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[whatRow][3]) {
if (pat->data[whatRow][0]==0 && pat->data[whatRow][1]==0) {
chan[i].midiAftertouch=true;
}
chan[i].volume=pat->data[whatRow][3]<<8;
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
}
@ -1436,6 +1444,11 @@ bool DivEngine::nextTick(bool noAccum) {
cycles++;
}
// MIDI clock
if (output) if (!skipping && output->midiOut!=NULL) {
output->midiOut->send(TAMidiMessage(TA_MIDI_CLOCK,0,0));
}
while (!pendingNotes.empty()) {
DivNoteEvent& note=pendingNotes.front();
if (note.on) {
@ -1732,8 +1745,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
if (!playing) {
if (out!=NULL) {
memcpy(oscBuf[0],out[0],size*sizeof(float));
memcpy(oscBuf[1],out[1],size*sizeof(float));
for (unsigned int i=0; i<size; i++) {
oscBuf[0][oscWritePos]=out[0][i];
oscBuf[1][oscWritePos]=out[1][i];
if (++oscWritePos>=32768) oscWritePos=0;
}
oscSize=size;
}
isBusy.unlock();
@ -1847,6 +1863,8 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
for (int i=0; i<song.systemLen; i++) {
float volL=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127-(int)song.systemPan[i])/127.0f)*song.masterVol;
float volR=((float)song.systemVol[i]/64.0f)*((float)MIN(127,127+(int)song.systemPan[i])/127.0f)*song.masterVol;
volL*=disCont[i].dispatch->getPostAmp();
volR*=disCont[i].dispatch->getPostAmp();
if (disCont[i].dispatch->isStereo()) {
for (size_t j=0; j<size; j++) {
out[0][j]+=((float)disCont[i].bbOut[0][j]/32768.0)*volL;
@ -1880,8 +1898,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
while (metroPos>=1) metroPos--;
}
memcpy(oscBuf[0],out[0],size*sizeof(float));
memcpy(oscBuf[1],out[1],size*sizeof(float));
for (unsigned int i=0; i<size; i++) {
oscBuf[0][oscWritePos]=out[0][i];
oscBuf[1][oscWritePos]=out[1][i];
if (++oscWritePos>=32768) oscWritePos=0;
}
oscSize=size;
if (forceMono) {

View file

@ -66,42 +66,6 @@ int SafeReader::read(void* where, size_t count) {
return count;
}
template<typename T>
int SafeReader::readByte(T* where, size_t count, unsigned char byte, Endianness endianness) {
if (byte==sizeof(T)) {
return read(where,count*byte);
} else {
#ifdef READ_DEBUG
logD("SR: reading %d x %d bit words at %x\n",count,byte<<3,curSeek);
#endif
if (count==0) return 0;
if (curSeek+(count*byte)>len) throw EndOfFileException(this,len);
int start,end,inc;
switch (endianness) {
case BigEndian:
start=byte-1;
end=-1;
inc=-1;
break;
case LittleEndian:
default:
start=0;
end=byte;
inc=1;
break;
}
for (int c=0; c<count; c++) {
T temp=0;
for (int b=start; b!=end; b+=inc) {
temp|=(buf[curSeek++]&0xff)<<(b<<3);
}
*where++=temp;
}
count*=byte;
}
return count;
}
signed char SafeReader::readC() {
#ifdef READ_DEBUG
logD("SR: reading char %x:\n",curSeek);

View file

@ -51,7 +51,6 @@ class SafeReader {
size_t size();
int read(void* where, size_t count);
template<typename T> int readByte(T* where, size_t count, unsigned char byte=sizeof(T), Endianness endianness=LittleEndian);
// these functions may throw EndOfFileException.
signed char readC();

View file

@ -73,39 +73,6 @@ int SafeWriter::write(const void* what, size_t count) {
return count;
}
template<typename T>
int SafeWriter::writeByte(T* what, size_t count, unsigned char byte, Endianness endianness) {
if (byte==sizeof(T)) {
return write(what,count*byte);
} else {
if (!operative) return 0;
checkSize(count*byte);
int start,end,inc;
switch (endianness) {
case BigEndian:
start=byte-1;
end=-1;
inc=-1;
break;
case LittleEndian:
default:
start=0;
end=byte;
inc=1;
break;
}
for (int c=0; c<count; c++) {
T temp=*what++;
for (int b=start; b!=end; b+=inc) {
buf[curSeek++]=(temp>>(byte<<3))&0xff;
}
}
count*=byte;
if (curSeek>len) len=curSeek;
}
return count;
}
int SafeWriter::writeC(signed char val) {
return write(&val,1);
}

View file

@ -43,7 +43,6 @@ class SafeWriter {
size_t size();
int write(const void* what, size_t count);
template<typename T> int writeByte(T* what, size_t count, unsigned char byte=sizeof(T), Endianness endianness=LittleEndian);
int writeC(signed char val);
int writeS(short val);