2022-02-14 22:12:20 -05:00
|
|
|
/**
|
|
|
|
* Furnace Tracker - multi-system chiptune tracker
|
|
|
|
* Copyright (C) 2021-2022 tildearrow and contributors
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2021-05-12 04:58:55 -04:00
|
|
|
#ifndef _ENGINE_H
|
|
|
|
#define _ENGINE_H
|
2021-05-11 16:08:08 -04:00
|
|
|
#include "song.h"
|
|
|
|
#include "dispatch.h"
|
2022-01-21 18:17:05 -05:00
|
|
|
#include "dataErrors.h"
|
2021-12-15 14:15:44 -05:00
|
|
|
#include "safeWriter.h"
|
2021-05-11 16:08:08 -04:00
|
|
|
#include "../audio/taAudio.h"
|
2021-05-12 04:58:55 -04:00
|
|
|
#include "blip_buf.h"
|
2022-01-17 23:34:29 -05:00
|
|
|
#include <thread>
|
2021-12-11 03:34:43 -05:00
|
|
|
#include <mutex>
|
2021-12-19 16:52:04 -05:00
|
|
|
#include <map>
|
2021-12-28 18:23:57 -05:00
|
|
|
#include <queue>
|
2021-05-11 16:08:08 -04:00
|
|
|
|
2022-02-09 22:07:32 -05:00
|
|
|
#define DIV_VERSION "0.5.6pre1"
|
|
|
|
#define DIV_ENGINE_VERSION 47
|
2021-12-16 02:21:43 -05:00
|
|
|
|
2021-05-19 03:05:24 -04:00
|
|
|
enum DivStatusView {
|
|
|
|
DIV_STATUS_NOTHING=0,
|
|
|
|
DIV_STATUS_PATTERN,
|
|
|
|
DIV_STATUS_COMMANDS
|
|
|
|
};
|
|
|
|
|
2021-06-09 04:33:03 -04:00
|
|
|
enum DivAudioEngines {
|
|
|
|
DIV_AUDIO_JACK=0,
|
2022-01-22 23:50:49 -05:00
|
|
|
DIV_AUDIO_SDL=1,
|
|
|
|
DIV_AUDIO_NULL=2,
|
|
|
|
DIV_AUDIO_DUMMY=3
|
2021-06-09 04:33:03 -04:00
|
|
|
};
|
|
|
|
|
2022-01-17 23:34:29 -05:00
|
|
|
enum DivAudioExportModes {
|
|
|
|
DIV_EXPORT_MODE_ONE=0,
|
|
|
|
DIV_EXPORT_MODE_MANY_SYS,
|
|
|
|
DIV_EXPORT_MODE_MANY_CHAN
|
|
|
|
};
|
|
|
|
|
2022-02-03 18:38:57 -05:00
|
|
|
enum DivHaltPositions {
|
|
|
|
DIV_HALT_NONE=0,
|
|
|
|
DIV_HALT_TICK,
|
|
|
|
DIV_HALT_ROW,
|
|
|
|
DIV_HALT_PATTERN,
|
|
|
|
DIV_HALT_BREAKPOINT
|
|
|
|
};
|
|
|
|
|
2021-05-11 16:08:08 -04:00
|
|
|
struct DivChannelState {
|
|
|
|
std::vector<DivDelayedCommand> delayed;
|
2021-12-19 00:02:48 -05:00
|
|
|
int note, oldNote, pitch, portaSpeed, portaNote;
|
2021-05-17 16:06:11 -04:00
|
|
|
int volume, volSpeed, cut, rowDelay, volMax;
|
2022-01-19 00:01:34 -05:00
|
|
|
int delayOrder, delayRow, retrigSpeed, retrigTick;
|
2021-05-18 04:02:47 -04:00
|
|
|
int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine;
|
2021-05-14 15:16:48 -04:00
|
|
|
int tremoloDepth, tremoloRate, tremoloPos;
|
2021-05-18 03:53:59 -04:00
|
|
|
unsigned char arp, arpStage, arpTicks;
|
2022-02-08 13:31:57 -05:00
|
|
|
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff, arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, noteOnInhibit;
|
2021-05-14 04:23:40 -04:00
|
|
|
|
|
|
|
DivChannelState():
|
|
|
|
note(-1),
|
2021-12-19 00:02:48 -05:00
|
|
|
oldNote(-1),
|
2021-05-14 04:23:40 -04:00
|
|
|
pitch(0),
|
|
|
|
portaSpeed(-1),
|
|
|
|
portaNote(-1),
|
|
|
|
volume(0x7f00),
|
|
|
|
volSpeed(0),
|
2021-05-16 04:03:23 -04:00
|
|
|
cut(-1),
|
|
|
|
rowDelay(0),
|
2021-12-16 15:51:19 -05:00
|
|
|
volMax(0),
|
2021-12-05 16:11:12 -05:00
|
|
|
delayOrder(0),
|
|
|
|
delayRow(0),
|
2022-01-19 00:01:34 -05:00
|
|
|
retrigSpeed(0),
|
|
|
|
retrigTick(0),
|
2021-05-14 04:23:40 -04:00
|
|
|
vibratoDepth(0),
|
|
|
|
vibratoRate(0),
|
2021-05-14 15:16:48 -04:00
|
|
|
vibratoPos(0),
|
2021-05-18 03:29:17 -04:00
|
|
|
vibratoDir(0),
|
2021-05-18 04:02:47 -04:00
|
|
|
vibratoFine(15),
|
2021-05-14 04:23:40 -04:00
|
|
|
tremoloDepth(0),
|
2021-05-14 15:16:48 -04:00
|
|
|
tremoloRate(0),
|
|
|
|
tremoloPos(0),
|
2021-05-16 04:03:23 -04:00
|
|
|
arp(0),
|
|
|
|
arpStage(-1),
|
2021-05-18 03:53:59 -04:00
|
|
|
arpTicks(1),
|
2021-12-08 00:27:20 -05:00
|
|
|
doNote(false),
|
|
|
|
legato(false),
|
|
|
|
portaStop(false),
|
|
|
|
keyOn(false),
|
2022-01-19 01:36:20 -05:00
|
|
|
keyOff(false),
|
2021-12-08 00:27:20 -05:00
|
|
|
nowYouCanStop(true),
|
|
|
|
stopOnOff(false),
|
|
|
|
arpYield(false),
|
2021-12-19 00:27:04 -05:00
|
|
|
delayLocked(false),
|
2022-01-19 01:27:32 -05:00
|
|
|
inPorta(false),
|
2022-02-03 01:30:03 -05:00
|
|
|
scheduledSlideReset(false),
|
2022-02-08 13:31:57 -05:00
|
|
|
shorthandPorta(false),
|
|
|
|
noteOnInhibit(false) {}
|
2021-05-11 16:08:08 -04:00
|
|
|
};
|
|
|
|
|
2021-12-28 18:23:57 -05:00
|
|
|
struct DivNoteEvent {
|
|
|
|
int channel, ins, note, volume;
|
|
|
|
bool on;
|
|
|
|
DivNoteEvent(int c, int i, int n, int v, bool o):
|
|
|
|
channel(c),
|
|
|
|
ins(i),
|
|
|
|
note(n),
|
|
|
|
volume(v),
|
|
|
|
on(o) {}
|
|
|
|
};
|
|
|
|
|
2022-01-03 03:35:13 -05:00
|
|
|
struct DivDispatchContainer {
|
|
|
|
DivDispatch* dispatch;
|
|
|
|
blip_buffer_t* bb[2];
|
|
|
|
size_t bbInLen;
|
|
|
|
int temp[2], prevSample[2];
|
|
|
|
short* bbIn[2];
|
|
|
|
short* bbOut[2];
|
2022-01-17 01:42:26 -05:00
|
|
|
bool lowQuality;
|
2022-01-08 16:03:32 -05:00
|
|
|
|
|
|
|
void setRates(double gotRate);
|
2022-01-17 01:42:26 -05:00
|
|
|
void setQuality(bool lowQual);
|
2022-01-08 17:15:12 -05:00
|
|
|
void acquire(size_t offset, size_t count);
|
2022-02-07 21:31:58 -05:00
|
|
|
void flush(size_t count);
|
|
|
|
void fillBuf(size_t runtotal, size_t offset, size_t size);
|
2022-01-08 16:03:32 -05:00
|
|
|
void clear();
|
2022-02-04 17:04:36 -05:00
|
|
|
void init(DivSystem sys, DivEngine* eng, int chanCount, double gotRate, unsigned int flags);
|
2022-01-08 16:03:32 -05:00
|
|
|
void quit();
|
|
|
|
DivDispatchContainer():
|
|
|
|
dispatch(NULL),
|
|
|
|
bb{NULL,NULL},
|
|
|
|
bbInLen(0),
|
|
|
|
temp{0,0},
|
|
|
|
prevSample{0,0},
|
|
|
|
bbIn{NULL,NULL},
|
2022-01-17 01:42:26 -05:00
|
|
|
bbOut{NULL,NULL},
|
|
|
|
lowQuality(false) {}
|
2022-01-03 03:35:13 -05:00
|
|
|
};
|
|
|
|
|
2021-05-11 16:08:08 -04:00
|
|
|
class DivEngine {
|
2022-01-08 16:03:32 -05:00
|
|
|
DivDispatchContainer disCont[32];
|
2021-05-11 16:08:08 -04:00
|
|
|
TAAudio* output;
|
|
|
|
TAAudioDesc want, got;
|
2022-01-17 23:34:29 -05:00
|
|
|
String exportPath;
|
|
|
|
std::thread* exportThread;
|
2021-05-11 16:08:08 -04:00
|
|
|
int chans;
|
2021-12-20 14:20:05 -05:00
|
|
|
bool active;
|
2022-01-17 01:42:26 -05:00
|
|
|
bool lowQuality;
|
2021-05-11 16:08:08 -04:00
|
|
|
bool playing;
|
2021-12-28 18:23:57 -05:00
|
|
|
bool freelance;
|
2021-05-11 16:08:08 -04:00
|
|
|
bool speedAB;
|
2021-12-07 04:22:36 -05:00
|
|
|
bool endOfSong;
|
2021-12-18 04:26:17 -05:00
|
|
|
bool consoleMode;
|
2021-12-20 19:46:49 -05:00
|
|
|
bool extValuePresent;
|
2021-12-21 17:42:27 -05:00
|
|
|
bool repeatPattern;
|
2022-01-04 00:02:41 -05:00
|
|
|
bool metronome;
|
2022-01-17 23:34:29 -05:00
|
|
|
bool exporting;
|
2022-02-03 18:38:57 -05:00
|
|
|
bool halted;
|
2022-02-04 17:04:36 -05:00
|
|
|
bool forceMono;
|
2022-01-12 02:45:26 -05:00
|
|
|
int ticks, curRow, curOrder, remainingLoops, nextSpeed, divider;
|
2022-02-06 00:42:07 -05:00
|
|
|
int cycles, clockDrift, stepPlay;
|
2022-01-12 02:45:26 -05:00
|
|
|
int changeOrd, changePos, totalSeconds, totalTicks, totalTicksR, totalCmds, lastCmds, cmdsPerSecond, globalPitch;
|
2021-12-20 19:46:49 -05:00
|
|
|
unsigned char extValue;
|
2021-12-21 02:30:09 -05:00
|
|
|
unsigned char speed1, speed2;
|
2021-05-19 03:05:24 -04:00
|
|
|
DivStatusView view;
|
2022-02-03 18:38:57 -05:00
|
|
|
DivHaltPositions haltOn;
|
2022-01-08 01:57:37 -05:00
|
|
|
DivChannelState chan[DIV_MAX_CHANS];
|
2021-06-09 04:33:03 -04:00
|
|
|
DivAudioEngines audioEngine;
|
2022-01-17 23:34:29 -05:00
|
|
|
DivAudioExportModes exportMode;
|
2021-12-19 16:52:04 -05:00
|
|
|
std::map<String,String> conf;
|
2021-12-28 18:23:57 -05:00
|
|
|
std::queue<DivNoteEvent> pendingNotes;
|
2022-01-08 01:57:37 -05:00
|
|
|
bool isMuted[DIV_MAX_CHANS];
|
2021-12-11 03:34:43 -05:00
|
|
|
std::mutex isBusy;
|
2021-12-19 03:16:24 -05:00
|
|
|
String configPath;
|
2021-12-19 16:52:04 -05:00
|
|
|
String configFile;
|
2021-12-20 23:20:30 -05:00
|
|
|
String lastError;
|
2022-01-29 01:22:32 -05:00
|
|
|
String warnings;
|
2022-02-13 21:42:57 -05:00
|
|
|
std::vector<String> audioDevs;
|
2021-05-11 16:08:08 -04:00
|
|
|
|
2021-12-21 13:06:14 -05:00
|
|
|
struct SamplePreview {
|
|
|
|
int sample;
|
2022-01-20 00:07:53 -05:00
|
|
|
int wave;
|
2021-12-21 13:06:14 -05:00
|
|
|
unsigned int pos;
|
|
|
|
SamplePreview():
|
|
|
|
sample(-1),
|
2022-01-20 00:07:53 -05:00
|
|
|
wave(-1),
|
2021-12-21 13:06:14 -05:00
|
|
|
pos(0) {}
|
|
|
|
} sPreview;
|
|
|
|
|
2021-05-16 04:03:23 -04:00
|
|
|
short vibTable[64];
|
2021-05-14 15:16:48 -04:00
|
|
|
|
2022-01-08 16:03:32 -05:00
|
|
|
blip_buffer_t* samp_bb;
|
|
|
|
size_t samp_bbInLen;
|
|
|
|
int samp_temp, samp_prevSample;
|
|
|
|
short* samp_bbIn;
|
|
|
|
short* samp_bbOut;
|
2022-01-04 00:02:41 -05:00
|
|
|
unsigned char* metroTick;
|
|
|
|
size_t metroTickLen;
|
2022-01-04 00:29:59 -05:00
|
|
|
float metroFreq, metroPos;
|
2022-01-04 00:02:41 -05:00
|
|
|
float metroAmp;
|
2021-05-12 04:58:55 -04:00
|
|
|
|
2021-12-08 02:57:41 -05:00
|
|
|
size_t totalProcessed;
|
|
|
|
|
2021-12-10 04:22:13 -05:00
|
|
|
private: int* jediTable;
|
|
|
|
|
2021-05-19 03:05:24 -04:00
|
|
|
int dispatchCmd(DivCommand c);
|
2021-05-16 04:03:23 -04:00
|
|
|
void processRow(int i, bool afterDelay);
|
2021-05-12 04:58:55 -04:00
|
|
|
void nextOrder();
|
|
|
|
void nextRow();
|
2022-01-27 13:10:51 -05:00
|
|
|
void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool isSecond);
|
2021-12-07 04:22:36 -05:00
|
|
|
// returns true if end of song.
|
2021-12-21 02:30:09 -05:00
|
|
|
bool nextTick(bool noAccum=false);
|
2021-05-13 03:39:26 -04:00
|
|
|
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
|
2021-05-15 04:13:21 -04:00
|
|
|
bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal);
|
2022-01-08 16:03:32 -05:00
|
|
|
void recalcChans();
|
2021-05-13 03:39:26 -04:00
|
|
|
void renderSamples();
|
2021-12-19 21:11:23 -05:00
|
|
|
void reset();
|
2022-02-06 00:07:35 -05:00
|
|
|
void playSub(bool preserveDrift, int goalRow=0);
|
2021-05-12 04:58:55 -04:00
|
|
|
|
2022-01-08 02:22:04 -05:00
|
|
|
bool loadDMF(unsigned char* file, size_t len);
|
|
|
|
bool loadFur(unsigned char* file, size_t len);
|
|
|
|
|
2022-01-17 01:20:02 -05:00
|
|
|
bool initAudioBackend();
|
|
|
|
bool deinitAudioBackend();
|
|
|
|
|
2022-02-07 23:42:54 -05:00
|
|
|
void exchangeIns(int one, int two);
|
|
|
|
|
2021-05-11 16:08:08 -04:00
|
|
|
public:
|
2021-05-12 18:19:18 -04:00
|
|
|
DivSong song;
|
2022-01-27 00:29:16 -05:00
|
|
|
DivSystem sysOfChan[DIV_MAX_CHANS];
|
|
|
|
int dispatchOfChan[DIV_MAX_CHANS];
|
|
|
|
int dispatchChanOfChan[DIV_MAX_CHANS];
|
2022-02-10 03:15:39 -05:00
|
|
|
bool keyHit[DIV_MAX_CHANS];
|
2022-01-27 17:49:00 -05:00
|
|
|
float* oscBuf[2];
|
|
|
|
float oscSize;
|
2022-01-27 00:29:16 -05:00
|
|
|
|
2022-01-17 23:34:29 -05:00
|
|
|
void runExportThread();
|
2021-05-12 04:58:55 -04:00
|
|
|
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
|
2021-05-16 21:49:54 -04:00
|
|
|
DivInstrument* getIns(int index);
|
2021-05-27 14:30:37 -04:00
|
|
|
DivWavetable* getWave(int index);
|
2021-12-24 18:23:01 -05:00
|
|
|
// start fresh
|
|
|
|
void createNew();
|
2022-01-08 02:22:04 -05:00
|
|
|
// load a file.
|
2021-12-16 02:21:43 -05:00
|
|
|
bool load(unsigned char* f, size_t length);
|
2021-05-11 16:08:08 -04:00
|
|
|
// save as .dmf.
|
2022-01-08 02:22:04 -05:00
|
|
|
SafeWriter* saveDMF();
|
|
|
|
// save as .fur.
|
|
|
|
SafeWriter* saveFur();
|
2022-01-16 23:21:27 -05:00
|
|
|
// build a ROM file (TODO).
|
|
|
|
// specify system to build ROM for.
|
|
|
|
SafeWriter* buildROM(int sys);
|
2022-01-27 02:46:40 -05:00
|
|
|
// dump to VGM.
|
|
|
|
SafeWriter* saveVGM(bool* sysToExport=NULL, bool loop=true);
|
2022-01-16 23:32:13 -05:00
|
|
|
// export to an audio file
|
2022-01-17 23:34:29 -05:00
|
|
|
bool saveAudio(const char* path, int loops, DivAudioExportModes mode);
|
2022-01-17 01:20:02 -05:00
|
|
|
// wait for audio export to finish
|
|
|
|
void waitAudioFile();
|
2022-01-16 23:32:13 -05:00
|
|
|
// stop audio file export
|
|
|
|
bool haltAudioFile();
|
2022-01-17 23:59:52 -05:00
|
|
|
// notify instrument parameter change
|
|
|
|
void notifyInsChange(int ins);
|
2022-01-18 00:25:10 -05:00
|
|
|
// notify wavetable change
|
|
|
|
void notifyWaveChange(int wave);
|
2021-05-11 16:08:08 -04:00
|
|
|
|
2022-01-26 00:26:15 -05:00
|
|
|
// returns whether a system is VGM compatible
|
|
|
|
bool isVGMExportable(DivSystem which);
|
|
|
|
|
2021-12-19 16:52:04 -05:00
|
|
|
// save config
|
|
|
|
bool saveConf();
|
|
|
|
|
|
|
|
// load config
|
|
|
|
bool loadConf();
|
|
|
|
|
|
|
|
// get a config value
|
|
|
|
bool getConfBool(String key, bool fallback);
|
|
|
|
int getConfInt(String key, int fallback);
|
|
|
|
float getConfFloat(String key, float fallback);
|
|
|
|
double getConfDouble(String key, double fallback);
|
|
|
|
String getConfString(String key, String fallback);
|
|
|
|
|
|
|
|
// set a config value
|
|
|
|
void setConf(String key, bool value);
|
|
|
|
void setConf(String key, int value);
|
|
|
|
void setConf(String key, float value);
|
|
|
|
void setConf(String key, double value);
|
|
|
|
void setConf(String key, String value);
|
|
|
|
|
2022-01-28 00:55:51 -05:00
|
|
|
// calculate base frequency/period
|
|
|
|
int calcBaseFreq(double clock, double divider, int note, bool period);
|
|
|
|
|
2021-12-28 00:51:38 -05:00
|
|
|
// calculate frequency/period
|
2022-02-03 02:24:11 -05:00
|
|
|
int calcFreq(int base, int pitch, bool period=false, int octave=0);
|
2021-12-28 00:51:38 -05:00
|
|
|
|
2022-01-25 15:06:29 -05:00
|
|
|
// find song loop position
|
2022-01-27 01:04:26 -05:00
|
|
|
void walkSong(int& loopOrder, int& loopRow, int& loopEnd);
|
2022-01-25 15:06:29 -05:00
|
|
|
|
2021-05-11 16:08:08 -04:00
|
|
|
// play
|
|
|
|
void play();
|
|
|
|
|
2022-02-06 00:07:35 -05:00
|
|
|
// play to row
|
|
|
|
void playToRow(int row);
|
|
|
|
|
2022-02-06 00:42:07 -05:00
|
|
|
// play by one row
|
|
|
|
void stepOne(int row);
|
|
|
|
|
2021-12-11 03:34:43 -05:00
|
|
|
// stop
|
|
|
|
void stop();
|
|
|
|
|
2021-12-15 00:37:27 -05:00
|
|
|
// reset playback state
|
2021-12-19 21:11:23 -05:00
|
|
|
void syncReset();
|
2021-12-15 00:37:27 -05:00
|
|
|
|
2021-12-21 13:06:14 -05:00
|
|
|
// trigger sample preview
|
2022-01-20 16:51:31 -05:00
|
|
|
void previewSample(int sample, int note=-1);
|
|
|
|
void stopSamplePreview();
|
2021-12-21 13:06:14 -05:00
|
|
|
|
2022-01-20 00:07:53 -05:00
|
|
|
// trigger wave preview
|
|
|
|
void previewWave(int wave, int note);
|
|
|
|
void stopWavePreview();
|
|
|
|
|
2021-12-19 03:16:24 -05:00
|
|
|
// get config path
|
|
|
|
String getConfigPath();
|
|
|
|
|
2021-12-12 04:21:09 -05:00
|
|
|
// get sys channel count
|
|
|
|
int getChannelCount(DivSystem sys);
|
|
|
|
|
2022-01-08 01:57:37 -05:00
|
|
|
// get channel count
|
2022-01-03 03:35:13 -05:00
|
|
|
int getTotalChannelCount();
|
|
|
|
|
2022-01-20 13:48:20 -05:00
|
|
|
// get effect description
|
|
|
|
const char* getEffectDesc(unsigned char effect, int chan);
|
|
|
|
|
2021-12-23 17:09:33 -05:00
|
|
|
// get channel type
|
|
|
|
// - 0: FM
|
|
|
|
// - 1: pulse
|
|
|
|
// - 2: noise
|
|
|
|
// - 3: wave/other
|
|
|
|
// - 4: PCM
|
|
|
|
// - 5: FM operator
|
|
|
|
int getChannelType(int ch);
|
|
|
|
|
2022-01-15 22:11:40 -05:00
|
|
|
// get preferred instrument type
|
|
|
|
DivInstrumentType getPreferInsType(int ch);
|
|
|
|
|
2021-12-15 17:32:08 -05:00
|
|
|
// get sys name
|
|
|
|
const char* getSystemName(DivSystem sys);
|
2022-01-25 18:46:27 -05:00
|
|
|
|
2022-01-28 03:17:35 -05:00
|
|
|
// get sys chips
|
|
|
|
const char* getSystemChips(DivSystem sys);
|
|
|
|
|
2022-01-25 18:46:27 -05:00
|
|
|
// get japanese system name
|
|
|
|
const char* getSystemNameJ(DivSystem sys);
|
2021-12-23 18:04:44 -05:00
|
|
|
|
|
|
|
// convert sample rate format
|
|
|
|
int fileToDivRate(int frate);
|
|
|
|
int divToFileRate(int drate);
|
|
|
|
|
|
|
|
// get effective sample rate
|
|
|
|
int getEffectiveSampleRate(int rate);
|
2021-12-15 17:32:08 -05:00
|
|
|
|
2021-12-12 04:21:09 -05:00
|
|
|
// is FM system
|
|
|
|
bool isFMSystem(DivSystem sys);
|
|
|
|
|
2021-12-17 22:14:41 -05:00
|
|
|
// is STD system
|
|
|
|
bool isSTDSystem(DivSystem sys);
|
|
|
|
|
2021-12-18 03:25:42 -05:00
|
|
|
// is channel muted
|
|
|
|
bool isChannelMuted(int chan);
|
|
|
|
|
|
|
|
// toggle mute
|
|
|
|
void toggleMute(int chan);
|
|
|
|
|
|
|
|
// toggle solo
|
|
|
|
void toggleSolo(int chan);
|
|
|
|
|
|
|
|
// set mute status
|
|
|
|
void muteChannel(int chan, bool mute);
|
|
|
|
|
2022-02-11 18:20:39 -05:00
|
|
|
// unmute all
|
|
|
|
void unmuteAll();
|
|
|
|
|
2021-12-13 13:10:56 -05:00
|
|
|
// get channel name
|
|
|
|
const char* getChannelName(int chan);
|
|
|
|
|
2021-12-12 04:21:09 -05:00
|
|
|
// get channel short name
|
|
|
|
const char* getChannelShortName(int chan);
|
|
|
|
|
2021-12-13 17:09:46 -05:00
|
|
|
// get channel max volume
|
|
|
|
int getMaxVolumeChan(int chan);
|
|
|
|
|
2021-12-11 03:34:43 -05:00
|
|
|
// get current order
|
|
|
|
unsigned char getOrder();
|
|
|
|
|
2021-12-13 17:09:46 -05:00
|
|
|
// get current row
|
|
|
|
int getRow();
|
|
|
|
|
2021-12-21 02:30:09 -05:00
|
|
|
// get speed 1
|
|
|
|
unsigned char getSpeed1();
|
|
|
|
|
|
|
|
// get speed 2
|
|
|
|
unsigned char getSpeed2();
|
|
|
|
|
|
|
|
// get Hz
|
|
|
|
int getHz();
|
|
|
|
|
2022-01-12 02:45:26 -05:00
|
|
|
// get current Hz
|
|
|
|
int getCurHz();
|
|
|
|
|
2021-12-21 02:30:09 -05:00
|
|
|
// get time
|
2022-01-12 02:45:26 -05:00
|
|
|
int getTotalTicks(); // 1/1000000th of a second
|
|
|
|
int getTotalSeconds();
|
2021-12-21 02:30:09 -05:00
|
|
|
|
2021-12-21 17:42:27 -05:00
|
|
|
// get repeat pattern
|
|
|
|
bool getRepeatPattern();
|
|
|
|
|
|
|
|
// set repeat pattern
|
|
|
|
void setRepeatPattern(bool value);
|
|
|
|
|
2021-12-20 19:46:49 -05:00
|
|
|
// has ext value
|
|
|
|
bool hasExtValue();
|
|
|
|
|
|
|
|
// get ext value
|
|
|
|
unsigned char getExtValue();
|
|
|
|
|
2021-12-13 17:09:46 -05:00
|
|
|
// is playing
|
|
|
|
bool isPlaying();
|
|
|
|
|
2022-02-06 00:42:07 -05:00
|
|
|
// is stepping
|
|
|
|
bool isStepping();
|
|
|
|
|
2022-01-17 23:34:29 -05:00
|
|
|
// is exporting
|
|
|
|
bool isExporting();
|
|
|
|
|
2021-12-17 03:33:12 -05:00
|
|
|
// add instrument
|
2022-01-09 23:50:26 -05:00
|
|
|
int addInstrument(int refChan=0);
|
2021-12-17 03:33:12 -05:00
|
|
|
|
2022-01-19 02:59:44 -05:00
|
|
|
// add instrument from file
|
2022-01-22 00:14:48 -05:00
|
|
|
bool addInstrumentFromFile(const char* path);
|
2022-01-19 02:59:44 -05:00
|
|
|
|
2021-12-17 03:33:12 -05:00
|
|
|
// delete instrument
|
|
|
|
void delInstrument(int index);
|
|
|
|
|
|
|
|
// add wavetable
|
|
|
|
int addWave();
|
|
|
|
|
2022-01-11 16:25:55 -05:00
|
|
|
// add wavetable from file
|
|
|
|
bool addWaveFromFile(const char* path);
|
|
|
|
|
2021-12-17 03:33:12 -05:00
|
|
|
// delete wavetable
|
|
|
|
void delWave(int index);
|
|
|
|
|
|
|
|
// add sample
|
|
|
|
int addSample();
|
|
|
|
|
|
|
|
// add sample from file
|
|
|
|
bool addSampleFromFile(const char* path);
|
|
|
|
|
|
|
|
// delete sample
|
|
|
|
void delSample(int index);
|
|
|
|
|
2021-12-22 17:39:16 -05:00
|
|
|
// add order
|
|
|
|
void addOrder(bool duplicate, bool where);
|
|
|
|
|
2022-02-12 03:59:05 -05:00
|
|
|
// deep clone orders
|
|
|
|
void deepCloneOrder(bool where);
|
|
|
|
|
2021-12-22 17:39:16 -05:00
|
|
|
// delete order
|
|
|
|
void deleteOrder();
|
|
|
|
|
|
|
|
// move order up
|
|
|
|
void moveOrderUp();
|
|
|
|
|
|
|
|
// move order down
|
|
|
|
void moveOrderDown();
|
|
|
|
|
2022-01-11 03:52:11 -05:00
|
|
|
// move thing up
|
|
|
|
bool moveInsUp(int which);
|
|
|
|
bool moveWaveUp(int which);
|
|
|
|
bool moveSampleUp(int which);
|
|
|
|
|
|
|
|
// move thing down
|
|
|
|
bool moveInsDown(int which);
|
|
|
|
bool moveWaveDown(int which);
|
|
|
|
bool moveSampleDown(int which);
|
|
|
|
|
2021-12-28 18:23:57 -05:00
|
|
|
// play note
|
|
|
|
void noteOn(int chan, int ins, int note, int vol=-1);
|
|
|
|
|
|
|
|
// stop note
|
|
|
|
void noteOff(int chan);
|
|
|
|
|
2021-12-11 03:34:43 -05:00
|
|
|
// go to order
|
|
|
|
void setOrder(unsigned char order);
|
|
|
|
|
2022-01-28 18:12:56 -05:00
|
|
|
// set system flags
|
2022-02-07 17:24:26 -05:00
|
|
|
void setSysFlags(int system, unsigned int flags, bool restart);
|
2022-01-28 18:12:56 -05:00
|
|
|
|
2021-12-15 17:32:08 -05:00
|
|
|
// set Hz
|
|
|
|
void setSongRate(int hz, bool pal);
|
|
|
|
|
2021-12-07 04:22:36 -05:00
|
|
|
// set remaining loops. -1 means loop forever.
|
|
|
|
void setLoops(int loops);
|
|
|
|
|
2022-01-27 00:29:16 -05:00
|
|
|
// get channel state
|
|
|
|
DivChannelState* getChanState(int chan);
|
|
|
|
|
|
|
|
// get dispatch channel state
|
|
|
|
void* getDispatchChanState(int chan);
|
|
|
|
|
2021-06-09 04:33:03 -04:00
|
|
|
// set the audio system.
|
|
|
|
void setAudio(DivAudioEngines which);
|
|
|
|
|
|
|
|
// set the view mode.
|
|
|
|
void setView(DivStatusView which);
|
|
|
|
|
2022-02-13 21:42:57 -05:00
|
|
|
// get available audio devices
|
|
|
|
std::vector<String>& getAudioDevices();
|
|
|
|
|
|
|
|
// rescan audio devices
|
|
|
|
void rescanAudioDevices();
|
|
|
|
|
2021-12-18 04:26:17 -05:00
|
|
|
// set the console mode.
|
|
|
|
void setConsoleMode(bool enable);
|
2022-01-04 00:02:41 -05:00
|
|
|
|
|
|
|
// get metronome
|
|
|
|
bool getMetronome();
|
|
|
|
|
|
|
|
// set metronome
|
|
|
|
void setMetronome(bool enable);
|
2021-12-18 04:26:17 -05:00
|
|
|
|
2022-02-03 18:38:57 -05:00
|
|
|
// halt now
|
|
|
|
void halt();
|
|
|
|
|
|
|
|
// resume from halt
|
|
|
|
void resume();
|
|
|
|
|
|
|
|
// halt on next something
|
|
|
|
void haltWhen(DivHaltPositions when);
|
|
|
|
|
|
|
|
// is engine halted
|
|
|
|
bool isHalted();
|
|
|
|
|
|
|
|
// get register cheatsheet
|
|
|
|
const char** getRegisterSheet(int sys);
|
|
|
|
|
2021-12-17 03:33:12 -05:00
|
|
|
// public render samples
|
|
|
|
void renderSamplesP();
|
|
|
|
|
2021-12-17 22:14:41 -05:00
|
|
|
// change system
|
2022-01-08 16:03:32 -05:00
|
|
|
void changeSystem(int index, DivSystem which);
|
|
|
|
|
|
|
|
// add system
|
2022-01-08 18:18:23 -05:00
|
|
|
bool addSystem(DivSystem which);
|
2022-01-08 16:03:32 -05:00
|
|
|
|
|
|
|
// remove system
|
2022-01-08 18:18:23 -05:00
|
|
|
bool removeSystem(int index);
|
2022-02-01 18:08:19 -05:00
|
|
|
|
|
|
|
// write to register on system
|
|
|
|
void poke(int sys, unsigned int addr, unsigned short val);
|
|
|
|
|
|
|
|
// write to register on system
|
|
|
|
void poke(int sys, std::vector<DivRegWrite>& wlist);
|
2021-12-17 22:14:41 -05:00
|
|
|
|
2021-12-20 23:20:30 -05:00
|
|
|
// get last error
|
|
|
|
String getLastError();
|
2022-01-29 01:22:32 -05:00
|
|
|
|
|
|
|
// get warnings
|
|
|
|
String getWarnings();
|
2022-01-17 01:42:26 -05:00
|
|
|
|
|
|
|
// switch master
|
2022-02-05 23:48:56 -05:00
|
|
|
bool switchMaster();
|
2021-12-20 23:20:30 -05:00
|
|
|
|
2022-02-05 21:26:24 -05:00
|
|
|
// get audio desc want
|
|
|
|
TAAudioDesc& getAudioDescWant();
|
|
|
|
|
|
|
|
// get audio desc
|
|
|
|
TAAudioDesc& getAudioDescGot();
|
|
|
|
|
2021-12-13 14:51:35 -05:00
|
|
|
// init dispatch
|
|
|
|
void initDispatch();
|
|
|
|
|
|
|
|
// quit dispatch
|
|
|
|
void quitDispatch();
|
|
|
|
|
2021-12-07 04:32:42 -05:00
|
|
|
// initialize the engine. optionally provide an output file name.
|
2022-01-16 23:32:13 -05:00
|
|
|
bool init();
|
2021-05-12 04:58:55 -04:00
|
|
|
|
2021-12-13 17:09:46 -05:00
|
|
|
// terminate the engine.
|
|
|
|
bool quit();
|
|
|
|
|
2021-12-10 23:41:00 -05:00
|
|
|
unsigned char* adpcmMem;
|
2022-01-24 02:52:45 -05:00
|
|
|
size_t adpcmMemLen;
|
2022-02-02 23:17:16 -05:00
|
|
|
unsigned char* adpcmBMem;
|
|
|
|
size_t adpcmBMemLen;
|
2021-12-10 23:41:00 -05:00
|
|
|
|
2021-05-12 04:58:55 -04:00
|
|
|
DivEngine():
|
2022-01-17 01:20:02 -05:00
|
|
|
output(NULL),
|
2022-01-17 23:34:29 -05:00
|
|
|
exportThread(NULL),
|
2021-05-12 04:58:55 -04:00
|
|
|
chans(0),
|
2021-12-20 14:20:05 -05:00
|
|
|
active(false),
|
2022-01-17 01:42:26 -05:00
|
|
|
lowQuality(false),
|
2021-05-12 04:58:55 -04:00
|
|
|
playing(false),
|
2021-12-28 18:23:57 -05:00
|
|
|
freelance(false),
|
2021-05-12 04:58:55 -04:00
|
|
|
speedAB(false),
|
2021-12-07 04:22:36 -05:00
|
|
|
endOfSong(false),
|
2021-12-18 04:26:17 -05:00
|
|
|
consoleMode(false),
|
2021-12-20 19:46:49 -05:00
|
|
|
extValuePresent(false),
|
2021-12-21 17:42:27 -05:00
|
|
|
repeatPattern(false),
|
2022-01-04 00:02:41 -05:00
|
|
|
metronome(false),
|
2022-01-17 23:34:29 -05:00
|
|
|
exporting(false),
|
2022-02-03 18:38:57 -05:00
|
|
|
halted(false),
|
2022-02-04 17:04:36 -05:00
|
|
|
forceMono(false),
|
2021-05-12 04:58:55 -04:00
|
|
|
ticks(0),
|
2021-12-05 16:11:12 -05:00
|
|
|
curRow(0),
|
2021-05-12 04:58:55 -04:00
|
|
|
curOrder(0),
|
2021-12-07 04:22:36 -05:00
|
|
|
remainingLoops(-1),
|
2021-12-08 00:27:20 -05:00
|
|
|
nextSpeed(3),
|
2022-01-12 02:45:26 -05:00
|
|
|
divider(60),
|
2022-01-12 17:45:07 -05:00
|
|
|
cycles(0),
|
|
|
|
clockDrift(0),
|
2022-02-06 00:42:07 -05:00
|
|
|
stepPlay(0),
|
2021-05-12 06:22:01 -04:00
|
|
|
changeOrd(-1),
|
|
|
|
changePos(0),
|
2022-01-12 02:45:26 -05:00
|
|
|
totalSeconds(0),
|
2021-05-19 03:05:24 -04:00
|
|
|
totalTicks(0),
|
2022-01-12 02:45:26 -05:00
|
|
|
totalTicksR(0),
|
2021-05-19 03:05:24 -04:00
|
|
|
totalCmds(0),
|
|
|
|
lastCmds(0),
|
|
|
|
cmdsPerSecond(0),
|
2021-12-20 19:46:49 -05:00
|
|
|
extValue(0),
|
2021-12-21 02:30:09 -05:00
|
|
|
speed1(3),
|
|
|
|
speed2(3),
|
2021-12-13 17:09:46 -05:00
|
|
|
view(DIV_STATUS_NOTHING),
|
2022-02-03 18:38:57 -05:00
|
|
|
haltOn(DIV_HALT_NONE),
|
2022-01-22 23:50:49 -05:00
|
|
|
audioEngine(DIV_AUDIO_NULL),
|
2022-01-08 16:03:32 -05:00
|
|
|
samp_bbInLen(0),
|
|
|
|
samp_temp(0),
|
|
|
|
samp_prevSample(0),
|
2022-01-04 00:02:41 -05:00
|
|
|
metroTick(NULL),
|
|
|
|
metroTickLen(0),
|
2022-01-04 00:29:59 -05:00
|
|
|
metroFreq(0),
|
2022-01-04 00:02:41 -05:00
|
|
|
metroPos(0),
|
|
|
|
metroAmp(0.0f),
|
2021-12-10 04:22:13 -05:00
|
|
|
totalProcessed(0),
|
2021-12-10 23:41:00 -05:00
|
|
|
jediTable(NULL),
|
2022-01-27 17:49:00 -05:00
|
|
|
oscBuf{NULL,NULL},
|
|
|
|
oscSize(1),
|
2022-01-24 02:52:45 -05:00
|
|
|
adpcmMem(NULL),
|
2022-02-02 23:17:16 -05:00
|
|
|
adpcmMemLen(0),
|
|
|
|
adpcmBMem(NULL),
|
|
|
|
adpcmBMemLen(0) {}
|
2021-05-11 16:08:08 -04:00
|
|
|
};
|
2021-05-12 06:22:01 -04:00
|
|
|
#endif
|