prepare for sample C-4 freq

issue #70
This commit is contained in:
tildearrow 2022-01-27 16:52:06 -05:00
parent 3d25cfc501
commit b812fc4041
6 changed files with 34 additions and 18 deletions

View file

@ -285,7 +285,8 @@ size | description
2 | volume 2 | volume
2 | pitch 2 | pitch
1 | depth 1 | depth
3 | reserved 1 | reserved
2 | C-4 rate (>=32)
4 | loop point (>=19) 4 | loop point (>=19)
| - -1 means no loop | - -1 means no loop
2?? | sample data (always 16-bit) 2?? | sample data (always 16-bit)

View file

@ -1425,7 +1425,13 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
sample->depth=reader.readC(); sample->depth=reader.readC();
// reserved // reserved
for (int j=0; j<3; j++) reader.readC(); reader.readC();
if (ds.version>=32) {
sample->centerRate=reader.readS();
} else {
reader.readS();
}
if (ds.version>=19) { if (ds.version>=19) {
sample->loopStart=reader.readI(); sample->loopStart=reader.readI();
@ -1757,9 +1763,8 @@ SafeWriter* DivEngine::saveFur() {
w->writeS(sample->vol); w->writeS(sample->vol);
w->writeS(sample->pitch); w->writeS(sample->pitch);
w->writeC(sample->depth); w->writeC(sample->depth);
for (int j=0; j<3; j++) { // reserved
w->writeC(0); w->writeC(0);
} w->writeS(sample->centerRate);
w->writeI(sample->loopStart); w->writeI(sample->loopStart);
w->write(sample->data,sample->length*2); w->write(sample->data,sample->length*2);

View file

@ -11,8 +11,8 @@
#include <map> #include <map>
#include <queue> #include <queue>
#define DIV_VERSION "0.5pre2" #define DIV_VERSION "0.5pre3"
#define DIV_ENGINE_VERSION 31 #define DIV_ENGINE_VERSION 32
enum DivStatusView { enum DivStatusView {
DIV_STATUS_NOTHING=0, DIV_STATUS_NOTHING=0,

View file

@ -20,8 +20,8 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
// PCM part // PCM part
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
if (chan[i].pcm && chan[i].dacSample!=-1) { if (chan[i].pcm && chan[i].dacSample!=-1) {
chan[i].dacPeriod-=6; chan[i].dacPeriod+=chan[i].dacRate;
if (chan[i].dacPeriod<1) { if (chan[i].dacPeriod>rate) {
DivSample* s=parent->song.sample[chan[i].dacSample]; DivSample* s=parent->song.sample[chan[i].dacSample];
if (s->rendLength<=0) { if (s->rendLength<=0) {
chan[i].dacSample=-1; chan[i].dacSample=-1;
@ -42,7 +42,7 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
chan[i].dacSample=-1; chan[i].dacSample=-1;
} }
} }
chan[i].dacPeriod+=chan[i].dacRate; chan[i].dacPeriod-=rate;
} }
} }
} }
@ -100,8 +100,12 @@ void DivPlatformPCE::tick() {
chan[i].std.next(); chan[i].std.next();
if (chan[i].std.hadVol) { if (chan[i].std.hadVol) {
chan[i].outVol=((chan[i].vol&31)*chan[i].std.vol)>>5; chan[i].outVol=((chan[i].vol&31)*chan[i].std.vol)>>5;
if (chan[i].furnaceDac) {
// ignore for now
} else {
chWrite(i,0x04,0x80|chan[i].outVol); chWrite(i,0x04,0x80|chan[i].outVol);
} }
}
if (chan[i].std.hadArp) { if (chan[i].std.hadArp) {
if (!chan[i].inPorta) { if (!chan[i].inPorta) {
if (chan[i].std.arpMode) { if (chan[i].std.arpMode) {
@ -132,8 +136,8 @@ void DivPlatformPCE::tick() {
//DivInstrument* ins=parent->getIns(chan[i].ins); //DivInstrument* ins=parent->getIns(chan[i].ins);
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true); chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true);
if (chan[i].furnaceDac) { if (chan[i].furnaceDac) {
chan[i].dacRate=chan[i].freq; chan[i].dacRate=1789773/chan[i].freq;
if (dumpWrites) addWrite(0xffff0001+(i<<8),1789773/chan[i].dacRate); if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dacRate);
} }
if (chan[i].freq>4095) chan[i].freq=4095; if (chan[i].freq>4095) chan[i].freq=4095;
if (chan[i].note>0x5d) chan[i].freq=0x01; if (chan[i].note>0x5d) chan[i].freq=0x01;
@ -187,6 +191,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
chan[c.chan].note=c.value; chan[c.chan].note=c.value;
} }
chan[c.chan].active=true; chan[c.chan].active=true;
chan[c.chan].std.init(ins);
//chan[c.chan].keyOn=true; //chan[c.chan].keyOn=true;
chan[c.chan].furnaceDac=true; chan[c.chan].furnaceDac=true;
} else { } else {
@ -200,10 +205,10 @@ int DivPlatformPCE::dispatch(DivCommand c) {
} }
chan[c.chan].dacPos=0; chan[c.chan].dacPos=0;
chan[c.chan].dacPeriod=0; chan[c.chan].dacPeriod=0;
chan[c.chan].dacRate=1789773/parent->song.sample[chan[c.chan].dacSample]->rate; chan[c.chan].dacRate=parent->song.sample[chan[c.chan].dacSample]->rate;
if (dumpWrites) { if (dumpWrites) {
chWrite(c.chan,0x04,0xdf); chWrite(c.chan,0x04,0xdf);
addWrite(0xffff0001+(c.chan<<8),1789773/chan[c.chan].dacRate); addWrite(0xffff0001+(c.chan<<8),chan[c.chan].dacRate);
} }
chan[c.chan].furnaceDac=false; chan[c.chan].furnaceDac=false;
} }

View file

@ -2,7 +2,7 @@
struct DivSample { struct DivSample {
String name; String name;
int length, rate, loopStart, loopOffP; int length, rate, centerRate, loopStart, loopOffP;
signed char vol, pitch; signed char vol, pitch;
unsigned char depth; unsigned char depth;
short* data; short* data;
@ -15,6 +15,7 @@ struct DivSample {
name(""), name(""),
length(0), length(0),
rate(32000), rate(32000),
centerRate(8363),
loopStart(-1), loopStart(-1),
loopOffP(0), loopOffP(0),
vol(0), vol(0),

View file

@ -1882,10 +1882,14 @@ void FurnaceGUI::drawSampleEdit() {
DivSample* sample=e->song.sample[curSample]; DivSample* sample=e->song.sample[curSample];
ImGui::InputText("Name",&sample->name); ImGui::InputText("Name",&sample->name);
ImGui::Text("Length: %d",sample->length); ImGui::Text("Length: %d",sample->length);
if (ImGui::SliderInt("Rate",&sample->rate,4000,32000,"%dHz")) { if (ImGui::InputInt("Rate (Hz)",&sample->rate,10,200)) {
if (sample->rate<4000) sample->rate=4000; if (sample->rate<100) sample->rate=100;
if (sample->rate>32000) sample->rate=32000; if (sample->rate>32000) sample->rate=32000;
} }
if (ImGui::InputInt("Pitch of C-4 (Hz)",&sample->centerRate,10,200)) {
if (sample->centerRate<100) sample->centerRate=100;
if (sample->centerRate>32000) sample->centerRate=32000;
}
ImGui::Text("effective rate: %dHz",e->getEffectiveSampleRate(sample->rate)); ImGui::Text("effective rate: %dHz",e->getEffectiveSampleRate(sample->rate));
bool doLoop=(sample->loopStart>=0); bool doLoop=(sample->loopStart>=0);
if (ImGui::Checkbox("Loop",&doLoop)) { if (ImGui::Checkbox("Loop",&doLoop)) {