mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 01:35:07 +00:00
parent
3d25cfc501
commit
b812fc4041
6 changed files with 34 additions and 18 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in a new issue