ZSM: include song tuning in export
This commit is contained in:
parent
a59b5753bb
commit
8006e40e26
4 changed files with 30 additions and 11 deletions
|
|
@ -116,6 +116,10 @@ void DivZSM::writeYM(unsigned char a, unsigned char v) {
|
|||
}
|
||||
}
|
||||
|
||||
void DivZSM::writeSync(unsigned char a, unsigned char v) {
|
||||
return syncCache.push_back(DivRegWrite(a,v));
|
||||
}
|
||||
|
||||
void DivZSM::writePSG(unsigned char a, unsigned char v) {
|
||||
// TODO: suppress writes to PSG voice that is not audible (volume=0)
|
||||
// ^ Let's leave these alone, ZSMKit has a feature that can benefit
|
||||
|
|
@ -126,7 +130,7 @@ void DivZSM::writePSG(unsigned char a, unsigned char v) {
|
|||
} else if (a==68) {
|
||||
// Sync event
|
||||
numWrites++;
|
||||
return syncCache.push_back(v);
|
||||
return writeSync(0x00,v);
|
||||
} else if (a>=64) {
|
||||
return writePCM(a-64,v);
|
||||
}
|
||||
|
|
@ -390,15 +394,18 @@ void DivZSM::flushWrites() {
|
|||
}
|
||||
}
|
||||
n=0;
|
||||
while (n<(long)syncCache.size()) { // we have one or more sync events to write
|
||||
int writes=syncCache.size()-n;
|
||||
w->writeC(ZSM_EXT);
|
||||
if (writes>ZSM_SYNC_MAX_WRITES) writes=ZSM_SYNC_MAX_WRITES;
|
||||
w->writeC(ZSM_EXT_SYNC|(writes<<1));
|
||||
for (; writes>0; writes--) {
|
||||
w->writeC(0x00); // 0x00 = Arbitrary sync message
|
||||
w->writeC(syncCache[n++]);
|
||||
for (DivRegWrite& write: syncCache) {
|
||||
if (n%ZSM_SYNC_MAX_WRITES==0) {
|
||||
w->writeC(ZSM_EXT);
|
||||
if (syncCache.size()-n>ZSM_SYNC_MAX_WRITES) {
|
||||
w->writeC((unsigned char)ZSM_EXT_SYNC|(ZSM_SYNC_MAX_WRITES<<1));
|
||||
} else {
|
||||
w->writeC((unsigned char)ZSM_EXT_SYNC|((syncCache.size()-n)<<1));
|
||||
}
|
||||
}
|
||||
n++;
|
||||
w->writeC(write.addr);
|
||||
w->writeC(write.val);
|
||||
}
|
||||
syncCache.clear();
|
||||
numWrites=0;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class DivZSM {
|
|||
std::vector<unsigned char> pcmData;
|
||||
std::vector<unsigned char> pcmCache;
|
||||
std::vector<S_pcmInst> pcmInsts;
|
||||
std::vector<unsigned char> syncCache;
|
||||
std::vector<DivRegWrite> syncCache;
|
||||
int loopOffset;
|
||||
int numWrites;
|
||||
int ticks;
|
||||
|
|
@ -78,6 +78,7 @@ class DivZSM {
|
|||
void writeYM(unsigned char a, unsigned char v);
|
||||
void writePSG(unsigned char a, unsigned char v);
|
||||
void writePCM(unsigned char a, unsigned char v);
|
||||
void writeSync(unsigned char a, unsigned char v);
|
||||
void tick(int numticks = 1);
|
||||
void setLoopPoint();
|
||||
SafeWriter* finish();
|
||||
|
|
|
|||
|
|
@ -107,6 +107,16 @@ SafeWriter* DivEngine::saveZSM(unsigned int zsmrate, bool loop) {
|
|||
// TODO: incorporate the Furnace meta-command for init data and filter
|
||||
// out writes to otherwise-unused channels.
|
||||
}
|
||||
// Indicate the song's tuning as a sync meta-event
|
||||
// specified in terms of how many 1/256th semitones
|
||||
// the song is offset from standard A-440 tuning.
|
||||
// This is mainly to benefit visualizations in players
|
||||
// for non-standard tunings so that they can avoid
|
||||
// displaying the entire song held in pitch bend.
|
||||
// Tunings offsets that exceed a half semitone
|
||||
// will simply be represented in a different key
|
||||
signed char tuningoffset=(signed char)round(3072*(log(song.tuning/440.0)/log(2)));
|
||||
zsm.writeSync(0x01,tuningoffset);
|
||||
|
||||
while (!done) {
|
||||
if (loopPos==-1) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue