GUI: play/stop/change order

This commit is contained in:
tildearrow 2021-12-11 03:34:43 -05:00
parent 9b850c1763
commit f39e2ea112
8 changed files with 95 additions and 19 deletions

View file

@ -103,6 +103,7 @@ class DivDispatch {
int rate;
virtual void acquire(short* bufL, short* bufR, size_t start, size_t len);
virtual int dispatch(DivCommand c);
virtual void reset();
virtual void tick();
virtual bool isStereo();

View file

@ -991,7 +991,43 @@ void DivEngine::setLoops(int loops) {
}
void DivEngine::play() {
isBusy.lock();
for (int i=0; i<17; i++) {
chan[i]=DivChannelState();
}
dispatch->reset();
playing=true;
curRow=0;
clockDrift=0;
cycles=0;
isBusy.unlock();
}
void DivEngine::stop() {
isBusy.lock();
playing=false;
isBusy.unlock();
}
unsigned char DivEngine::getOrder() {
return curOrder;
}
void DivEngine::setOrder(unsigned char order) {
isBusy.lock();
curOrder=order;
if (order>=song.ordersLen) curOrder=0;
if (playing) {
for (int i=0; i<17; i++) {
chan[i]=DivChannelState();
}
dispatch->reset();
playing=true;
curRow=0;
clockDrift=0;
cycles=0;
}
isBusy.unlock();
}
void DivEngine::setAudio(DivAudioEngines which) {

View file

@ -4,6 +4,7 @@
#include "dispatch.h"
#include "../audio/taAudio.h"
#include "blip_buf.h"
#include <mutex>
enum DivStatusView {
DIV_STATUS_NOTHING=0,
@ -71,6 +72,7 @@ class DivEngine {
DivStatusView view;
DivChannelState chan[17];
DivAudioEngines audioEngine;
std::mutex isBusy;
short vibTable[64];
@ -107,6 +109,15 @@ class DivEngine {
// play
void play();
// stop
void stop();
// get current order
unsigned char getOrder();
// go to order
void setOrder(unsigned char order);
// set remaining loops. -1 means loop forever.
void setLoops(int loops);

View file

@ -10,6 +10,9 @@ int DivDispatch::dispatch(DivCommand c) {
return 1;
}
void DivDispatch::reset() {
}
bool DivDispatch::isStereo() {
return false;
}

View file

@ -471,25 +471,11 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
return 1;
}
bool DivPlatformYM2610::isStereo() {
return true;
}
bool DivPlatformYM2610::keyOffAffectsArp(int ch) {
return (ch>3);
}
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, bool pal) {
parent=p;
if (pal) {
rate=500000;
} else {
rate=500000;
}
iface.parent=parent;
iface.sampleBank=0;
fm=new ymfm::ym2610(iface);
void DivPlatformYM2610::reset() {
fm->reset();
for (int i=0; i<13; i++) {
chan[i]=DivPlatformYM2610::Channel();
}
for (int i=0; i<4; i++) {
chan[i].vol=0x7f;
}
@ -523,5 +509,26 @@ int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, bool pal) {
// PCM volume
writes.emplace(0x101,0x3f);
}
bool DivPlatformYM2610::isStereo() {
return true;
}
bool DivPlatformYM2610::keyOffAffectsArp(int ch) {
return (ch>3);
}
int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, bool pal) {
parent=p;
if (pal) {
rate=500000;
} else {
rate=500000;
}
iface.parent=parent;
iface.sampleBank=0;
fm=new ymfm::ym2610(iface);
reset();
return 10;
}

View file

@ -61,6 +61,7 @@ class DivPlatformYM2610: public DivDispatch {
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void reset();
void tick();
bool isStereo();
bool keyOffAffectsArp(int ch);

View file

@ -774,6 +774,11 @@ bool DivEngine::nextTick() {
}
void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) {
if (!playing) {
memset(out[0],0,size*sizeof(float));
memset(out[1],0,size*sizeof(float));
return;
}
size_t runtotal=blip_clocks_needed(bb[0],size);
if (runtotal>bbInLen) {
@ -787,6 +792,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
size_t runLeft=runtotal;
size_t runPos=0;
totalProcessed=0;
isBusy.lock();
while (runLeft) {
if (!remainingLoops) {
memset(bbIn[0]+runPos,0,runLeft*sizeof(short));
@ -811,6 +817,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
}
}
}
isBusy.unlock();
totalProcessed=(1+runPos)*got.rate/dispatch->rate;
for (size_t i=0; i<runtotal; i++) {

View file

@ -28,6 +28,16 @@ bool FurnaceGUI::loop() {
ImGui::Text("Hello world!\n");
ImGui::InputScalar("Speed 1",ImGuiDataType_U8,&e->song.speed1);
ImGui::InputScalar("Speed 2",ImGuiDataType_U8,&e->song.speed2);
unsigned char ord=e->getOrder();
if (ImGui::InputScalar("Order",ImGuiDataType_U8,&ord)) {
e->setOrder(ord);
}
if (ImGui::Button("Play")) {
e->play();
}
if (ImGui::Button("Stop")) {
e->stop();
}
}
ImGui::End();