From 113a1577b68022d0044ed7b3adb0687eb8192157 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 15 Jan 2022 17:28:33 -0500 Subject: [PATCH] do the Amiga --- CMakeLists.txt | 1 + src/engine/dispatchContainer.cpp | 4 ++ src/engine/engine.cpp | 8 +++- src/engine/platform/amiga.cpp | 82 ++++++++++++-------------------- src/engine/platform/amiga.h | 12 +++-- src/gui/gui.cpp | 16 +++++++ 6 files changed, 66 insertions(+), 57 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cbbfe51..61ac5a1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ src/engine/platform/ay.cpp src/engine/platform/ay8930.cpp src/engine/platform/tia.cpp src/engine/platform/saa.cpp +src/engine/platform/amiga.cpp src/engine/platform/dummy.cpp) set(GUI_SOURCES diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index 4836428a..50126b1d 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -13,6 +13,7 @@ #include "platform/ay8930.h" #include "platform/tia.h" #include "platform/saa.h" +#include "platform/amiga.h" #include "platform/dummy.h" #include "../ta-log.h" @@ -116,6 +117,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do case DIV_SYSTEM_YM2610_EXT: dispatch=new DivPlatformYM2610Ext; break; + case DIV_SYSTEM_AMIGA: + dispatch=new DivPlatformAmiga; + break; case DIV_SYSTEM_AY8910: dispatch=new DivPlatformAY8910; break; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index ee67920f..cb0ea2b1 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2815,10 +2815,14 @@ bool DivEngine::addSampleFromFile(const char* path) { for (int i=0; idata[index++]=averaged^(((si.format&SF_FORMAT_SUBMASK)==SF_FORMAT_PCM_U8)?0x8000:0); + sample->data[index++]=averaged; } delete[] buf; sample->rate=si.samplerate; diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index ce73c3a9..49d05308 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -2,33 +2,39 @@ #include "../engine.h" #include -#define FREQ_BASE 1712.0f +#define FREQ_BASE 6848.0f #define AMIGA_DIVIDER 8 void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t len) { for (size_t h=start; hsong.sample[chan[i].dacSample]; + if (chan[i].audSub<0) { + DivSample* s=parent->song.sample[chan[i].sample]; if (s->depth==8) { - chan[i].audOut=s->rendData[chan[i].audPos]; + chan[i].audDat=s->rendData[chan[i].audPos++]; } else { - chan[i].audOut=s->rendData[chan[i].audPos]>>8; + chan[i].audDat=s->rendData[chan[i].audPos++]>>8; } if (chan[i].audPos>=s->rendLength) { - chan[i].audSample=-1; + chan[i].sample=-1; } chan[i].audSub+=chan[i].freq; } } + if (!isMuted[i]) { + if (i==0 || i==3) { + bufL[h]+=(chan[i].audDat*chan[i].outVol); + bufR[h]+=(chan[i].audDat*chan[i].outVol)>>2; + } else { + bufL[h]+=(chan[i].audDat*chan[i].outVol)>>2; + bufR[h]+=(chan[i].audDat*chan[i].outVol); + } + } } - bufL[h]=(chan[0].audOut*chan[0].outVol)+; - (chan[3].audOut*chan[3].outVol); - bufR[h]=(chan[1].audOut*chan[1].outVol)+; - (chan[2].audOut*chan[2].outVol); } } @@ -56,19 +62,18 @@ void DivPlatformAmiga::tick() { if (chan[i].std.hadWave) { if (chan[i].wave!=chan[i].std.wave) { chan[i].wave=chan[i].std.wave; - updateWave(i); if (!chan[i].keyOff) chan[i].keyOn=true; } } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { //DivInstrument* ins=parent->getIns(chan[i].ins); chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true); + printf("freq[%d]=%d\n",i,chan[i].freq); if (chan[i].freq>4095) chan[i].freq=4095; if (chan[i].note>0x5d) chan[i].freq=0x01; if (chan[i].keyOn) { if (chan[i].wave<0) { chan[i].wave=0; - updateWave(i); } } if (chan[i].keyOff) { @@ -82,28 +87,24 @@ void DivPlatformAmiga::tick() { int DivPlatformAmiga::dispatch(DivCommand c) { switch (c.cmd) { - case DIV_CMD_NOTE_ON: - if (chan[c.chan].pcm) { - chan[c.chan].dacSample=12*sampleBank+c.value%12; - if (chan[c.chan].dacSample>=parent->song.sampleLen) { - chan[c.chan].dacSample=-1; - break; - } - chan[c.chan].dacPos=0; - chan[c.chan].dacPeriod=0; - chan[c.chan].dacRate=1789773/parent->song.sample[chan[c.chan].dacSample]->rate; - break; - } + case DIV_CMD_NOTE_ON: { + DivInstrument* ins=parent->getIns(chan[c.chan].ins); chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)c.value/12.0f))); + chan[c.chan].sample=ins->amiga.initSample; + if (chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) { + chan[c.chan].sample=-1; + } + chan[c.chan].audPos=0; + chan[c.chan].audSub=0; chan[c.chan].freqChanged=true; chan[c.chan].note=c.value; chan[c.chan].active=true; chan[c.chan].keyOn=true; - chan[c.chan].std.init(parent->getIns(chan[c.chan].ins)); + chan[c.chan].std.init(ins); break; + } case DIV_CMD_NOTE_OFF: - chan[c.chan].dacSample=-1; - chan[c.chan].pcm=false; + chan[c.chan].sample=-1; chan[c.chan].active=false; chan[c.chan].keyOff=true; chan[c.chan].std.init(NULL); @@ -133,7 +134,6 @@ int DivPlatformAmiga::dispatch(DivCommand c) { break; case DIV_CMD_WAVE: chan[c.chan].wave=c.value; - updateWave(c.chan); chan[c.chan].keyOn=true; break; case DIV_CMD_NOTE_PORTA: { @@ -159,22 +159,6 @@ int DivPlatformAmiga::dispatch(DivCommand c) { } break; } - case DIV_CMD_STD_NOISE_MODE: - chan[c.chan].noise=c.value; - break; - case DIV_CMD_SAMPLE_MODE: - chan[c.chan].pcm=c.value; - break; - case DIV_CMD_SAMPLE_BANK: - sampleBank=c.value; - if (sampleBank>(parent->song.sample.size()/12)) { - sampleBank=parent->song.sample.size()/12; - } - break; - case DIV_CMD_PANNING: { - chan[c.chan].pan=c.value; - break; - } case DIV_CMD_LEGATO: chan[c.chan].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(c.value+((chan[c.chan].std.willArp && !chan[c.chan].std.arpMode)?(chan[c.chan].std.arp-12):(0)))/12.0f))); chan[c.chan].freqChanged=true; @@ -247,8 +231,4 @@ int DivPlatformAmiga::init(DivEngine* p, int channels, int sugRate, bool pal) { } void DivPlatformAmiga::quit() { - delete pce; -} - -DivPlatformAmiga::~DivPlatformAmiga() { -} +} \ No newline at end of file diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 1e956a2e..595bbe08 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -1,5 +1,5 @@ -#ifndef _PCE_H -#define _PCE_H +#ifndef _AMIGA_H +#define _AMIGA_H #include "../dispatch.h" #include @@ -11,10 +11,11 @@ class DivPlatformAmiga: public DivDispatch { unsigned int audLoc; unsigned short audLen; unsigned int audPos; + int audSub; signed char audDat; - int sample; + int sample, wave; unsigned char ins, note; - bool active, insChanged, freqChanged, keyOn, keyOff, inPorta; + bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave; signed char vol, outVol; DivMacroInt std; Channel(): @@ -24,8 +25,10 @@ class DivPlatformAmiga: public DivDispatch { audLoc(0), audLen(0), audPos(0), + audSub(0), audDat(0), sample(-1), + wave(0), ins(-1), note(0), active(false), @@ -34,6 +37,7 @@ class DivPlatformAmiga: public DivDispatch { keyOn(false), keyOff(false), inPorta(false), + useWave(false), vol(64), outVol(64) {} }; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0b7fdb1d..e77a5c19 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -761,6 +761,22 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndTabItem(); } if (ins->type==DIV_INS_AMIGA) if (ImGui::BeginTabItem("Amiga")) { + String sName; + if (ins->amiga.initSample<0 || ins->amiga.initSample>=e->song.sampleLen) { + sName="none selected"; + } else { + sName=e->song.sample[ins->amiga.initSample]->name; + } + if (ImGui::BeginCombo("Initial Sample",sName.c_str())) { + String id; + for (int i=0; isong.sampleLen; i++) { + id=fmt::sprintf("%d: %s",i,e->song.sample[i]->name); + if (ImGui::Selectable(id.c_str(),ins->amiga.initSample==i)) { + ins->amiga.initSample=i; + } + } + ImGui::EndCombo(); + } ImGui::EndTabItem(); } if (ins->type!=DIV_INS_FM) if (ImGui::BeginTabItem("Macros")) {