furnace/src/engine/engine.h

152 lines
3.4 KiB
C
Raw Normal View History

#ifndef _ENGINE_H
#define _ENGINE_H
#include "song.h"
#include "dispatch.h"
#include "../audio/taAudio.h"
#include "blip_buf.h"
enum DivStatusView {
DIV_STATUS_NOTHING=0,
DIV_STATUS_PATTERN,
DIV_STATUS_COMMANDS
};
2021-06-09 08:33:03 +00:00
enum DivAudioEngines {
DIV_AUDIO_JACK=0,
2021-12-07 09:32:42 +00:00
DIV_AUDIO_SDL
2021-06-09 08:33:03 +00:00
};
struct DivChannelState {
std::vector<DivDelayedCommand> delayed;
2021-05-14 08:23:40 +00:00
int note, pitch, portaSpeed, portaNote;
int volume, volSpeed, cut, rowDelay, volMax;
int delayOrder, delayRow;
2021-05-18 08:02:47 +00:00
int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine;
int tremoloDepth, tremoloRate, tremoloPos;
2021-05-18 07:53:59 +00:00
unsigned char arp, arpStage, arpTicks;
bool doNote, legato, portaStop, keyOn, nowYouCanStop, stopOnOff, arpYield, delayLocked;
2021-05-14 08:23:40 +00:00
DivChannelState():
note(-1),
pitch(0),
portaSpeed(-1),
portaNote(-1),
volume(0x7f00),
volSpeed(0),
cut(-1),
rowDelay(0),
delayOrder(0),
delayRow(0),
2021-05-14 08:23:40 +00:00
vibratoDepth(0),
vibratoRate(0),
vibratoPos(0),
vibratoDir(0),
2021-05-18 08:02:47 +00:00
vibratoFine(15),
2021-05-14 08:23:40 +00:00
tremoloDepth(0),
tremoloRate(0),
tremoloPos(0),
arp(0),
arpStage(-1),
2021-05-18 07:53:59 +00:00
arpTicks(1),
doNote(false),
legato(false),
portaStop(false),
keyOn(false),
nowYouCanStop(true),
stopOnOff(false),
arpYield(false),
delayLocked(false) {}
};
class DivEngine {
DivDispatch* dispatch;
TAAudio* output;
TAAudioDesc want, got;
int chans;
bool playing;
bool speedAB;
bool endOfSong;
2021-12-08 07:57:41 +00:00
int ticks, cycles, curRow, curOrder, remainingLoops, nextSpeed, clockDrift;
int changeOrd, changePos, totalTicks, totalCmds, lastCmds, cmdsPerSecond;
DivStatusView view;
2021-05-14 08:23:40 +00:00
DivChannelState chan[17];
2021-06-09 08:33:03 +00:00
DivAudioEngines audioEngine;
short vibTable[64];
blip_buffer_t* bb[2];
size_t bbInLen;
int temp[2], prevSample[2];
short* bbIn[2];
short* bbOut[2];
2021-12-08 07:57:41 +00:00
size_t totalProcessed;
2021-12-10 09:22:13 +00:00
private: int* jediTable;
int dispatchCmd(DivCommand c);
void processRow(int i, bool afterDelay);
void nextOrder();
void nextRow();
// returns true if end of song.
bool nextTick();
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal);
void renderSamples();
public:
2021-05-12 22:19:18 +00:00
DivSong song;
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
DivInstrument* getIns(int index);
DivWavetable* getWave(int index);
// load a .dmf.
bool load(void* f, size_t length);
// save as .dmf.
bool save(FILE* f);
// play
void play();
// set remaining loops. -1 means loop forever.
void setLoops(int loops);
2021-06-09 08:33:03 +00:00
// set the audio system.
void setAudio(DivAudioEngines which);
// set the view mode.
void setView(DivStatusView which);
2021-12-07 09:32:42 +00:00
// initialize the engine. optionally provide an output file name.
bool init(String outName="");
2021-12-11 04:41:00 +00:00
unsigned char* adpcmMem;
DivEngine():
chans(0),
playing(false),
speedAB(false),
endOfSong(false),
ticks(0),
cycles(0),
curRow(0),
curOrder(0),
remainingLoops(-1),
nextSpeed(3),
2021-12-08 07:57:41 +00:00
clockDrift(0),
changeOrd(-1),
changePos(0),
totalTicks(0),
totalCmds(0),
lastCmds(0),
cmdsPerSecond(0),
view(DIV_STATUS_PATTERN),
2021-06-09 08:33:03 +00:00
audioEngine(DIV_AUDIO_SDL),
bbInLen(0),
temp{0,0},
2021-12-10 09:22:13 +00:00
prevSample{0,0},
totalProcessed(0),
2021-12-11 04:41:00 +00:00
jediTable(NULL),
adpcmMem(NULL) {}
};
#endif