Merge branch 'master' of https://github.com/tildearrow/furnace into ymf289b
This commit is contained in:
commit
3d345af1b8
|
@ -0,0 +1 @@
|
|||
<!-- NOTICE: if you are going to write a suggestion, see the Discussions section instead. any suggestions posted in Issues will be closed. -->
|
|
@ -11,7 +11,7 @@ defaults:
|
|||
shell: bash
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
BUILD_TYPE: Debug
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -20,13 +20,13 @@ jobs:
|
|||
config:
|
||||
- { name: 'Windows MSVC x86', os: windows-latest, compiler: msvc, arch: x86 }
|
||||
- { name: 'Windows MSVC x86_64', os: windows-latest, compiler: msvc, arch: x86_64 }
|
||||
- { name: 'Windows MinGW x86', os: ubuntu-20.04, compiler: mingw, arch: x86 }
|
||||
- { name: 'Windows MinGW x86_64', os: ubuntu-20.04, compiler: mingw, arch: x86_64 }
|
||||
##- { name: 'Windows MinGW x86', os: ubuntu-20.04, compiler: mingw, arch: x86 }
|
||||
##- { name: 'Windows MinGW x86_64', os: ubuntu-20.04, compiler: mingw, arch: x86_64 }
|
||||
- { name: 'macOS x86_64', os: macos-latest, arch: x86_64 }
|
||||
- { name: 'macOS ARM', os: macos-latest, arch: arm64 }
|
||||
- { name: 'Linux x86_64', os: ubuntu-18.04, arch: x86_64 }
|
||||
##- { name: 'Linux x86_64', os: ubuntu-18.04, arch: x86_64 }
|
||||
#- { name: 'Linux ARM', os: ubuntu-18.04, arch: armhf }
|
||||
fail-fast: true
|
||||
fail-fast: false
|
||||
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
|
|
@ -753,7 +753,7 @@ if (WARNINGS_ARE_ERRORS)
|
|||
)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
if (WIN32)
|
||||
add_executable(furnace WIN32 ${USED_SOURCES})
|
||||
elseif(ANDROID AND NOT TERMUX)
|
||||
add_library(furnace SHARED ${USED_SOURCES})
|
||||
|
|
|
@ -15,8 +15,8 @@ android {
|
|||
}
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 26
|
||||
versionCode 113
|
||||
versionName "dev113"
|
||||
versionCode 136
|
||||
versionName "dev136"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -946,10 +946,8 @@ static void OPL3_ChannelSetupAlg(opl3_channel *channel)
|
|||
}
|
||||
}
|
||||
|
||||
static void OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
||||
static void OPL3_ChannelUpdateAlg(opl3_channel *channel)
|
||||
{
|
||||
channel->fb = (data & 0x0e) >> 1;
|
||||
channel->con = data & 0x01;
|
||||
channel->alg = channel->con;
|
||||
if (channel->chip->newm)
|
||||
{
|
||||
|
@ -974,14 +972,25 @@ static void OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
|||
{
|
||||
OPL3_ChannelSetupAlg(channel);
|
||||
}
|
||||
}
|
||||
|
||||
static void OPL3_ChannelWriteC0(opl3_channel *channel, uint8_t data)
|
||||
{
|
||||
channel->fb = (data & 0x0e) >> 1;
|
||||
channel->con = data & 0x01;
|
||||
OPL3_ChannelUpdateAlg(channel);
|
||||
if (channel->chip->newm)
|
||||
{
|
||||
channel->cha = ((data >> 4) & 0x01) ? ~0 : 0;
|
||||
channel->chb = ((data >> 5) & 0x01) ? ~0 : 0;
|
||||
channel->chc = ((data >> 6) & 0x01) ? ~0 : 0;
|
||||
channel->chd = ((data >> 7) & 0x01) ? ~0 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->cha = channel->chb = (uint16_t)~0;
|
||||
// TODO: Verify on real chip if DAC2 output is disabled in compat mode
|
||||
channel->chc = channel->chd = 0;
|
||||
}
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
if (!channel->chip->stereoext)
|
||||
|
@ -1066,11 +1075,14 @@ static void OPL3_ChannelSet4Op(opl3_chip *chip, uint8_t data)
|
|||
{
|
||||
chip->channel[chnum].chtype = ch_4op;
|
||||
chip->channel[chnum + 3].chtype = ch_4op2;
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
}
|
||||
else
|
||||
{
|
||||
chip->channel[chnum].chtype = ch_2op;
|
||||
chip->channel[chnum + 3].chtype = ch_2op;
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum]);
|
||||
OPL3_ChannelUpdateAlg(&chip->channel[chnum+3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1096,17 +1108,18 @@ static void OPL3_ProcessSlot(opl3_slot *slot)
|
|||
OPL3_SlotGenerate(slot);
|
||||
}
|
||||
|
||||
void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
||||
inline void OPL3_Generate4Ch(opl3_chip *chip, int16_t *buf4)
|
||||
{
|
||||
opl3_channel *channel;
|
||||
opl3_writebuf *writebuf;
|
||||
int16_t **out;
|
||||
int32_t mix;
|
||||
int32_t mix[2];
|
||||
uint8_t ii;
|
||||
int16_t accm;
|
||||
uint8_t shift = 0;
|
||||
|
||||
buf[1] = OPL3_ClipSample(chip->mixbuff[1]);
|
||||
buf4[1] = OPL3_ClipSample(chip->mixbuff[1]);
|
||||
buf4[3] = OPL3_ClipSample(chip->mixbuff[3]);
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 0; ii < 15; ii++)
|
||||
|
@ -1117,7 +1130,7 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
OPL3_ProcessSlot(&chip->slot[ii]);
|
||||
}
|
||||
|
||||
mix = 0;
|
||||
mix[0] = mix[1] = 0;
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
channel = &chip->channel[ii];
|
||||
|
@ -1125,12 +1138,14 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix += (int16_t)((accm * channel->leftpan) >> 16);
|
||||
mix[0] += (int16_t)((accm * channel->leftpan) >> 16);
|
||||
#else
|
||||
mix += (int16_t)(accm & channel->cha);
|
||||
#endif
|
||||
mix[0] += (int16_t)(accm & channel->cha);
|
||||
#endif
|
||||
mix[1] += (int16_t)(accm & channel->chc);
|
||||
}
|
||||
chip->mixbuff[0] = mix;
|
||||
chip->mixbuff[0] = mix[0];
|
||||
chip->mixbuff[2] = mix[1];
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 15; ii < 18; ii++)
|
||||
|
@ -1139,7 +1154,8 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
buf[0] = OPL3_ClipSample(chip->mixbuff[0]);
|
||||
buf4[0] = OPL3_ClipSample(chip->mixbuff[0]);
|
||||
buf4[2] = OPL3_ClipSample(chip->mixbuff[2]);
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 18; ii < 33; ii++)
|
||||
|
@ -1148,7 +1164,7 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
}
|
||||
#endif
|
||||
|
||||
mix = 0;
|
||||
mix[0] = mix[1] = 0;
|
||||
for (ii = 0; ii < 18; ii++)
|
||||
{
|
||||
channel = &chip->channel[ii];
|
||||
|
@ -1156,12 +1172,14 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
out = channel->out;
|
||||
accm = *out[0] + *out[1] + *out[2] + *out[3];
|
||||
#if OPL_ENABLE_STEREOEXT
|
||||
mix += (int16_t)((accm * channel->rightpan) >> 16);
|
||||
mix[0] += (int16_t)((accm * channel->rightpan) >> 16);
|
||||
#else
|
||||
mix += (int16_t)(accm & channel->chb);
|
||||
#endif
|
||||
mix[0] += (int16_t)(accm & channel->chb);
|
||||
#endif
|
||||
mix[1] += (int16_t)(accm & channel->chd);
|
||||
}
|
||||
chip->mixbuff[1] = mix;
|
||||
chip->mixbuff[1] = mix[0];
|
||||
chip->mixbuff[3] = mix[1];
|
||||
|
||||
#if OPL_QUIRK_CHANNELSAMPLEDELAY
|
||||
for (ii = 33; ii < 36; ii++)
|
||||
|
@ -1236,22 +1254,44 @@ void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
|||
chip->writebuf_samplecnt++;
|
||||
}
|
||||
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf)
|
||||
void OPL3_Generate(opl3_chip *chip, int16_t *buf)
|
||||
{
|
||||
int16_t samples[4];
|
||||
OPL3_Generate4Ch(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void OPL3_Generate4ChResampled(opl3_chip *chip, int16_t *buf4)
|
||||
{
|
||||
while (chip->samplecnt >= chip->rateratio)
|
||||
{
|
||||
chip->oldsamples[0] = chip->samples[0];
|
||||
chip->oldsamples[1] = chip->samples[1];
|
||||
OPL3_Generate(chip, chip->samples);
|
||||
chip->oldsamples[2] = chip->samples[2];
|
||||
chip->oldsamples[3] = chip->samples[3];
|
||||
OPL3_Generate4Ch(chip, chip->samples);
|
||||
chip->samplecnt -= chip->rateratio;
|
||||
}
|
||||
buf[0] = (int16_t)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf[1] = (int16_t)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[0] = (int16_t)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[0] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[1] = (int16_t)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[1] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[2] = (int16_t)((chip->oldsamples[2] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[2] * chip->samplecnt) / chip->rateratio);
|
||||
buf4[3] = (int16_t)((chip->oldsamples[3] * (chip->rateratio - chip->samplecnt)
|
||||
+ chip->samples[3] * chip->samplecnt) / chip->rateratio);
|
||||
chip->samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
|
||||
void OPL3_GenerateResampled(opl3_chip *chip, int16_t *buf)
|
||||
{
|
||||
int16_t samples[4];
|
||||
OPL3_Generate4ChResampled(chip, samples);
|
||||
buf[0] = samples[0];
|
||||
buf[1] = samples[1];
|
||||
}
|
||||
|
||||
void OPL3_Reset(opl3_chip *chip, uint32_t samplerate)
|
||||
{
|
||||
opl3_slot *slot;
|
||||
|
@ -1464,9 +1504,26 @@ void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v)
|
|||
chip->writebuf_last = (writebuf_last + 1) % OPL_WRITEBUF_SIZE;
|
||||
}
|
||||
|
||||
void OPL3_Generate4ChStream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples)
|
||||
{
|
||||
uint_fast32_t i;
|
||||
int16_t samples[4];
|
||||
|
||||
for(i = 0; i < numsamples; i++)
|
||||
{
|
||||
OPL3_Generate4ChResampled(chip, samples);
|
||||
sndptr1[0] = samples[0];
|
||||
sndptr1[1] = samples[1];
|
||||
sndptr2[0] = samples[2];
|
||||
sndptr2[1] = samples[3];
|
||||
sndptr1 += 2;
|
||||
sndptr2 += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples)
|
||||
{
|
||||
uint32_t i;
|
||||
uint_fast32_t i;
|
||||
|
||||
for(i = 0; i < numsamples; i++)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,7 @@ struct _opl3_channel {
|
|||
uint8_t alg;
|
||||
uint8_t ksv;
|
||||
uint16_t cha, chb;
|
||||
uint16_t chc, chd;
|
||||
uint8_t ch_num;
|
||||
uint8_t muted;
|
||||
};
|
||||
|
@ -129,7 +130,7 @@ struct _opl3_chip {
|
|||
uint8_t tremoloshift;
|
||||
uint32_t noise;
|
||||
int16_t zeromod;
|
||||
int32_t mixbuff[2];
|
||||
int32_t mixbuff[4];
|
||||
uint8_t rm_hh_bit2;
|
||||
uint8_t rm_hh_bit3;
|
||||
uint8_t rm_hh_bit7;
|
||||
|
@ -144,8 +145,8 @@ struct _opl3_chip {
|
|||
/* OPL3L */
|
||||
int32_t rateratio;
|
||||
int32_t samplecnt;
|
||||
int16_t oldsamples[2];
|
||||
int16_t samples[2];
|
||||
int16_t oldsamples[4];
|
||||
int16_t samples[4];
|
||||
|
||||
uint64_t writebuf_samplecnt;
|
||||
uint32_t writebuf_cur;
|
||||
|
@ -161,6 +162,10 @@ void OPL3_WriteReg(opl3_chip *chip, uint16_t reg, uint8_t v);
|
|||
void OPL3_WriteRegBuffered(opl3_chip *chip, uint16_t reg, uint8_t v);
|
||||
void OPL3_GenerateStream(opl3_chip *chip, int16_t *sndptr, uint32_t numsamples);
|
||||
|
||||
void OPL3_Generate4Ch(opl3_chip *chip, int16_t *buf4);
|
||||
void OPL3_Generate4ChResampled(opl3_chip *chip, int16_t *buf4);
|
||||
void OPL3_Generate4ChStream(opl3_chip *chip, int16_t *sndptr1, int16_t *sndptr2, uint32_t numsamples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,9 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
|||
|
||||
the format versions are:
|
||||
|
||||
- 136: Furnace dev136
|
||||
- 135: Furnace dev135
|
||||
- 134: Furnace dev134
|
||||
- 133: Furnace 0.6pre3
|
||||
- 132: Furnace 0.6pre2
|
||||
- 131: Furnace dev131
|
||||
|
@ -386,8 +389,42 @@ size | description
|
|||
STR | song author (Japanese)
|
||||
STR | system name (Japanese)
|
||||
STR | album/category/game name (Japanese)
|
||||
--- | **extra chip output settings (× chipCount)** (>=135)
|
||||
4f | chip volume
|
||||
4f | chip panning
|
||||
4f | chip front/rear balance
|
||||
--- | **patchbay** (>=135)
|
||||
4 | patchbay connection count
|
||||
4?? | patchbay
|
||||
| - see next section for more details.
|
||||
1 | automatic patchbay (>=136)
|
||||
```
|
||||
|
||||
# patchbay
|
||||
|
||||
Furnace dev135 adds a "patchbay" which allows for arbitrary connection of chip outputs to system outputs.
|
||||
it eventually will allow connecting outputs to effects and so on.
|
||||
|
||||
a connection is represented as an unsigned int in the following format:
|
||||
|
||||
- bit 16-31: source port
|
||||
- bit 0-15: destination port
|
||||
|
||||
a port is in the following format (hexadecimal): `xxxy`
|
||||
|
||||
- `xxx` (bit 4 to 15) represents a portset.
|
||||
- `y` (bit 0 to 3) is the port in that portset.
|
||||
|
||||
reserved input portsets:
|
||||
- `000`: system outputs
|
||||
- `FFF`: "null" portset
|
||||
|
||||
reserved output portsets:
|
||||
- `000` through `01F`: chip outputs
|
||||
- `FFD`: wave/sample preview
|
||||
- `FFE`: metronome
|
||||
- `FFF`: "null" portset
|
||||
|
||||
# subsong
|
||||
|
||||
from version 95 onwards, Furnace supports storing multiple songs on a single file.
|
||||
|
|
|
@ -33,4 +33,7 @@
|
|||
// sample related
|
||||
#define DIV_MAX_SAMPLE_TYPE 4
|
||||
|
||||
// dispatch
|
||||
#define DIV_MAX_OUTPUTS 16
|
||||
|
||||
#endif
|
||||
|
|
|
@ -213,6 +213,8 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_MACRO_OFF, // (which)
|
||||
DIV_CMD_MACRO_ON, // (which)
|
||||
|
||||
DIV_CMD_SURROUND_PANNING, // (out, val)
|
||||
|
||||
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
||||
|
||||
DIV_CMD_MAX
|
||||
|
@ -322,12 +324,10 @@ class DivDispatch {
|
|||
|
||||
/**
|
||||
* fill a buffer with sound data.
|
||||
* @param bufL the left or mono channel buffer.
|
||||
* @param bufR the right channel buffer.
|
||||
* @param start the start offset.
|
||||
* @param buf pointers to output buffers.
|
||||
* @param len the amount of samples to fill.
|
||||
*/
|
||||
virtual void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
virtual void acquire(short** buf, size_t len);
|
||||
|
||||
/**
|
||||
* fill a write stream with data (e.g. for software-mixed PCM).
|
||||
|
@ -413,10 +413,10 @@ class DivDispatch {
|
|||
virtual void muteChannel(int ch, bool mute);
|
||||
|
||||
/**
|
||||
* test whether this dispatch outputs audio in two channels.
|
||||
* @return whether it does.
|
||||
* get the number of outputs this dispatch provides.
|
||||
* @return number of outputs (usually 1 or 2 but may be more). SHALL NOT be less than one.
|
||||
*/
|
||||
virtual bool isStereo();
|
||||
virtual int getOutputCount();
|
||||
|
||||
/**
|
||||
* test whether sending a key off command to a channel should reset arp too.
|
||||
|
|
|
@ -80,79 +80,131 @@
|
|||
#include "song.h"
|
||||
|
||||
void DivDispatchContainer::setRates(double gotRate) {
|
||||
blip_set_rates(bb[0],dispatch->rate,gotRate);
|
||||
blip_set_rates(bb[1],dispatch->rate,gotRate);
|
||||
int outs=dispatch->getOutputCount();
|
||||
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bb[i]==NULL) continue;
|
||||
blip_set_rates(bb[i],dispatch->rate,gotRate);
|
||||
}
|
||||
rateMemory=gotRate;
|
||||
}
|
||||
|
||||
void DivDispatchContainer::setQuality(bool lowQual) {
|
||||
lowQuality=lowQual;
|
||||
}
|
||||
|
||||
void DivDispatchContainer::grow(size_t size) {
|
||||
bbInLen=size;
|
||||
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||
if (bbIn[i]!=NULL) {
|
||||
delete[] bbIn[i];
|
||||
bbIn[i]=new short[bbInLen];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_MISSING_BUFS \
|
||||
int outs=dispatch->getOutputCount(); \
|
||||
\
|
||||
/* create missing buffers if any */ \
|
||||
bool mustClear=false; \
|
||||
for (int i=0; i<outs; i++) { \
|
||||
if (bb[i]==NULL) { \
|
||||
logV("creating buf %d because it doesn't exist",i); \
|
||||
bb[i]=blip_new(bbInLen); \
|
||||
if (bb[i]==NULL) { \
|
||||
logE("not enough memory!"); \
|
||||
return; \
|
||||
} \
|
||||
blip_set_rates(bb[i],dispatch->rate,rateMemory); \
|
||||
\
|
||||
if (bbIn[i]==NULL) bbIn[i]=new short[bbInLen]; \
|
||||
if (bbOut[i]==NULL) bbOut[i]=new short[bbInLen]; \
|
||||
memset(bbIn[i],0,bbInLen*sizeof(short)); \
|
||||
memset(bbOut[i],0,bbInLen*sizeof(short)); \
|
||||
mustClear=true; \
|
||||
} \
|
||||
} \
|
||||
if (mustClear) clear(); \
|
||||
|
||||
void DivDispatchContainer::acquire(size_t offset, size_t count) {
|
||||
dispatch->acquire(bbIn[0],bbIn[1],offset,count);
|
||||
CHECK_MISSING_BUFS;
|
||||
|
||||
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||
if (i>=outs) {
|
||||
bbInMapped[i]=NULL;
|
||||
} else {
|
||||
if (bbIn[i]==NULL) {
|
||||
bbInMapped[i]=NULL;
|
||||
} else {
|
||||
bbInMapped[i]=&bbIn[i][offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch->acquire(bbInMapped,count);
|
||||
}
|
||||
|
||||
void DivDispatchContainer::flush(size_t count) {
|
||||
blip_read_samples(bb[0],bbOut[0],count,0);
|
||||
int outs=dispatch->getOutputCount();
|
||||
|
||||
if (dispatch->isStereo()) {
|
||||
blip_read_samples(bb[1],bbOut[1],count,0);
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bb[i]==NULL) continue;
|
||||
blip_read_samples(bb[i],bbOut[i],count,0);
|
||||
}
|
||||
}
|
||||
|
||||
void DivDispatchContainer::fillBuf(size_t runtotal, size_t offset, size_t size) {
|
||||
CHECK_MISSING_BUFS;
|
||||
|
||||
if (dcOffCompensation && runtotal>0) {
|
||||
dcOffCompensation=false;
|
||||
prevSample[0]=bbIn[0][0];
|
||||
if (dispatch->isStereo()) prevSample[1]=bbIn[1][0];
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bbIn[i]==NULL) continue;
|
||||
prevSample[i]=bbIn[i][0];
|
||||
}
|
||||
}
|
||||
if (lowQuality) {
|
||||
for (size_t i=0; i<runtotal; i++) {
|
||||
temp[0]=bbIn[0][i];
|
||||
blip_add_delta_fast(bb[0],i,temp[0]-prevSample[0]);
|
||||
prevSample[0]=temp[0];
|
||||
}
|
||||
|
||||
if (dispatch->isStereo()) for (size_t i=0; i<runtotal; i++) {
|
||||
temp[1]=bbIn[1][i];
|
||||
blip_add_delta_fast(bb[1],i,temp[1]-prevSample[1]);
|
||||
prevSample[1]=temp[1];
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bbIn[i]==NULL) continue;
|
||||
if (bb[i]==NULL) continue;
|
||||
for (size_t j=0; j<runtotal; j++) {
|
||||
temp[i]=bbIn[i][j];
|
||||
blip_add_delta_fast(bb[i],j,temp[i]-prevSample[i]);
|
||||
prevSample[i]=temp[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (size_t i=0; i<runtotal; i++) {
|
||||
temp[0]=bbIn[0][i];
|
||||
blip_add_delta(bb[0],i,temp[0]-prevSample[0]);
|
||||
prevSample[0]=temp[0];
|
||||
}
|
||||
|
||||
if (dispatch->isStereo()) for (size_t i=0; i<runtotal; i++) {
|
||||
temp[1]=bbIn[1][i];
|
||||
blip_add_delta(bb[1],i,temp[1]-prevSample[1]);
|
||||
prevSample[1]=temp[1];
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bbIn[i]==NULL) continue;
|
||||
if (bb[i]==NULL) continue;
|
||||
for (size_t j=0; j<runtotal; j++) {
|
||||
temp[i]=bbIn[i][j];
|
||||
blip_add_delta(bb[i],j,temp[i]-prevSample[i]);
|
||||
prevSample[i]=temp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blip_end_frame(bb[0],runtotal);
|
||||
blip_read_samples(bb[0],bbOut[0]+offset,size,0);
|
||||
for (int i=0; i<outs; i++) {
|
||||
if (bbOut[i]==NULL) continue;
|
||||
if (bb[i]==NULL) continue;
|
||||
blip_end_frame(bb[i],runtotal);
|
||||
blip_read_samples(bb[i],bbOut[i]+offset,size,0);
|
||||
}
|
||||
/*if (totalRead<(int)size && totalRead>0) {
|
||||
for (size_t i=totalRead; i<size; i++) {
|
||||
bbOut[0][i]=bbOut[0][totalRead-1];//bbOut[0][totalRead];
|
||||
}
|
||||
}*/
|
||||
|
||||
if (dispatch->isStereo()) {
|
||||
blip_end_frame(bb[1],runtotal);
|
||||
blip_read_samples(bb[1],bbOut[1]+offset,size,0);
|
||||
}
|
||||
}
|
||||
|
||||
void DivDispatchContainer::clear() {
|
||||
blip_clear(bb[0]);
|
||||
blip_clear(bb[1]);
|
||||
temp[0]=0;
|
||||
temp[1]=0;
|
||||
prevSample[0]=0;
|
||||
prevSample[1]=0;
|
||||
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||
if (bb[i]!=NULL) blip_clear(bb[i]);
|
||||
temp[i]=0;
|
||||
prevSample[i]=0;
|
||||
}
|
||||
|
||||
if (dispatch->getDCOffRequired()) {
|
||||
dcOffCompensation=true;
|
||||
}
|
||||
|
@ -166,26 +218,10 @@ void DivDispatchContainer::clear() {
|
|||
}
|
||||
|
||||
void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, double gotRate, const DivConfig& flags) {
|
||||
// quit if we already initialized
|
||||
if (dispatch!=NULL) return;
|
||||
|
||||
bb[0]=blip_new(32768);
|
||||
if (bb[0]==NULL) {
|
||||
logE("not enough memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
bb[1]=blip_new(32768);
|
||||
if (bb[1]==NULL) {
|
||||
logE("not enough memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
bbOut[0]=new short[32768];
|
||||
bbOut[1]=new short[32768];
|
||||
bbIn[0]=new short[32768];
|
||||
bbIn[1]=new short[32768];
|
||||
bbInLen=32768;
|
||||
|
||||
// initialize chip
|
||||
switch (sys) {
|
||||
case DIV_SYSTEM_YMU759:
|
||||
dispatch=new DivPlatformOPL;
|
||||
|
@ -461,6 +497,23 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
break;
|
||||
}
|
||||
dispatch->init(eng,chanCount,gotRate,flags);
|
||||
|
||||
// initialize output buffers
|
||||
int outs=dispatch->getOutputCount();
|
||||
bbInLen=32768;
|
||||
|
||||
for (int i=0; i<outs; i++) {
|
||||
bb[i]=blip_new(bbInLen);
|
||||
if (bb[i]==NULL) {
|
||||
logE("not enough memory!");
|
||||
return;
|
||||
}
|
||||
|
||||
bbIn[i]=new short[bbInLen];
|
||||
bbOut[i]=new short[bbInLen];
|
||||
memset(bbIn[i],0,bbInLen*sizeof(short));
|
||||
memset(bbOut[i],0,bbInLen*sizeof(short));
|
||||
}
|
||||
}
|
||||
|
||||
void DivDispatchContainer::quit() {
|
||||
|
@ -469,11 +522,19 @@ void DivDispatchContainer::quit() {
|
|||
delete dispatch;
|
||||
dispatch=NULL;
|
||||
|
||||
delete[] bbOut[0];
|
||||
delete[] bbOut[1];
|
||||
delete[] bbIn[0];
|
||||
delete[] bbIn[1];
|
||||
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||
if (bbOut[i]!=NULL) {
|
||||
delete[] bbOut[i];
|
||||
bbOut[i]=NULL;
|
||||
}
|
||||
if (bbIn[i]!=NULL) {
|
||||
delete[] bbIn[i];
|
||||
bbIn[i]=NULL;
|
||||
}
|
||||
if (bb[i]!=NULL) {
|
||||
blip_delete(bb[i]);
|
||||
bb[i]=NULL;
|
||||
}
|
||||
}
|
||||
bbInLen=0;
|
||||
blip_delete(bb[0]);
|
||||
blip_delete(bb[1]);
|
||||
}
|
||||
|
|
|
@ -77,6 +77,15 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
return "81xx: Set panning (left channel)";
|
||||
case 0x82:
|
||||
return "82xx: Set panning (right channel)";
|
||||
case 0x88:
|
||||
return "88xx: Set panning (rear channels; x: left; y: right)";
|
||||
break;
|
||||
case 0x89:
|
||||
return "89xx: Set panning (rear left channel)";
|
||||
break;
|
||||
case 0x8a:
|
||||
return "8Axx: Set panning (rear right channel)";
|
||||
break;
|
||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||
return "Cxxx: Set tick rate (hz)";
|
||||
case 0xe0:
|
||||
|
@ -435,6 +444,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
|||
case DIV_CMD_FM_FINE:
|
||||
case DIV_CMD_AY_IO_WRITE:
|
||||
case DIV_CMD_AY_AUTO_PWM:
|
||||
case DIV_CMD_SURROUND_PANNING:
|
||||
w->writeC(2); // length
|
||||
w->writeC(c.value);
|
||||
w->writeC(c.value2);
|
||||
|
@ -897,11 +907,7 @@ void DivEngine::runExportThread() {
|
|||
for (int i=0; i<song.systemLen; i++) {
|
||||
sf[i]=NULL;
|
||||
si[i].samplerate=got.rate;
|
||||
if (disCont[i].dispatch->isStereo()) {
|
||||
si[i].channels=2;
|
||||
} else {
|
||||
si[i].channels=1;
|
||||
}
|
||||
si[i].channels=disCont[i].dispatch->getOutputCount();
|
||||
si[i].format=SF_FORMAT_WAV|SF_FORMAT_PCM_16;
|
||||
}
|
||||
|
||||
|
@ -944,11 +950,12 @@ void DivEngine::runExportThread() {
|
|||
if (isFadingOut) {
|
||||
double mul=(1.0-((double)curFadeOutSample/(double)fadeOutSamples));
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
if (!disCont[i].dispatch->isStereo()) {
|
||||
sysBuf[i][j]=(double)disCont[i].bbOut[0][j]*mul;
|
||||
} else {
|
||||
sysBuf[i][j<<1]=(double)disCont[i].bbOut[0][j]*mul;
|
||||
sysBuf[i][1+(j<<1)]=(double)disCont[i].bbOut[1][j]*mul;
|
||||
for (int k=0; k<si[i].channels; k++) {
|
||||
if (disCont[i].bbOut[k]==NULL) {
|
||||
sysBuf[i][k+(j*si[i].channels)]=0;
|
||||
} else {
|
||||
sysBuf[i][k+(j*si[i].channels)]=(double)disCont[i].bbOut[k][j]*mul;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (++curFadeOutSample>=fadeOutSamples) {
|
||||
|
@ -957,11 +964,12 @@ void DivEngine::runExportThread() {
|
|||
}
|
||||
} else {
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
if (!disCont[i].dispatch->isStereo()) {
|
||||
sysBuf[i][j]=disCont[i].bbOut[0][j];
|
||||
} else {
|
||||
sysBuf[i][j<<1]=disCont[i].bbOut[0][j];
|
||||
sysBuf[i][1+(j<<1)]=disCont[i].bbOut[1][j];
|
||||
for (int k=0; k<si[i].channels; k++) {
|
||||
if (disCont[i].bbOut[k]==NULL) {
|
||||
sysBuf[i][k+(j*si[i].channels)]=0;
|
||||
} else {
|
||||
sysBuf[i][k+(j*si[i].channels)]=disCont[i].bbOut[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastLoopPos>-1 && j>=lastLoopPos && totalLoops>=exportLoopCount) {
|
||||
|
@ -1333,8 +1341,8 @@ String DivEngine::decodeSysDesc(String desc) {
|
|||
int val=0;
|
||||
int curStage=0;
|
||||
int sysID=0;
|
||||
int sysVol=0;
|
||||
int sysPan=0;
|
||||
float sysVol=0;
|
||||
float sysPan=0;
|
||||
int sysFlags=0;
|
||||
int curSys=0;
|
||||
desc+=' '; // ha
|
||||
|
@ -1349,24 +1357,25 @@ String DivEngine::decodeSysDesc(String desc) {
|
|||
curStage++;
|
||||
break;
|
||||
case 1:
|
||||
sysVol=val;
|
||||
sysVol=(float)val/64.0f;
|
||||
curStage++;
|
||||
break;
|
||||
case 2:
|
||||
sysPan=val;
|
||||
sysPan=(float)val/127.0f;
|
||||
curStage++;
|
||||
break;
|
||||
case 3:
|
||||
sysFlags=val;
|
||||
|
||||
if (sysID!=0) {
|
||||
if (sysVol<-128) sysVol=-128;
|
||||
if (sysVol>127) sysVol=127;
|
||||
if (sysPan<-128) sysPan=-128;
|
||||
if (sysPan>127) sysPan=127;
|
||||
if (sysVol<-1.0f) sysVol=-1.0f;
|
||||
if (sysVol>1.0f) sysVol=1.0f;
|
||||
if (sysPan<-1.0f) sysPan=-1.0f;
|
||||
if (sysPan>1.0f) sysPan=1.0f;
|
||||
newDesc.set(fmt::sprintf("id%d",curSys),sysID);
|
||||
newDesc.set(fmt::sprintf("vol%d",curSys),sysVol);
|
||||
newDesc.set(fmt::sprintf("pan%d",curSys),sysPan);
|
||||
newDesc.set(fmt::sprintf("fr%d",curSys),0.0f);
|
||||
DivConfig newFlagsC;
|
||||
newFlagsC.clear();
|
||||
convertOldFlags((unsigned int)sysFlags,newFlagsC,systemFromFileFur(sysID));
|
||||
|
@ -1396,7 +1405,7 @@ String DivEngine::decodeSysDesc(String desc) {
|
|||
return newDesc.toBase64();
|
||||
}
|
||||
|
||||
void DivEngine::initSongWithDesc(const char* description, bool inBase64) {
|
||||
void DivEngine::initSongWithDesc(const char* description, bool inBase64, bool oldVol) {
|
||||
int chanCount=0;
|
||||
DivConfig c;
|
||||
if (inBase64) {
|
||||
|
@ -1415,9 +1424,16 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64) {
|
|||
song.system[index]=DIV_SYSTEM_NULL;
|
||||
break;
|
||||
}
|
||||
song.systemVol[index]=c.getInt(fmt::sprintf("vol%d",index),DIV_SYSTEM_NULL);
|
||||
song.systemPan[index]=c.getInt(fmt::sprintf("pan%d",index),DIV_SYSTEM_NULL);
|
||||
song.systemVol[index]=c.getFloat(fmt::sprintf("vol%d",index),1.0f);
|
||||
song.systemPan[index]=c.getFloat(fmt::sprintf("pan%d",index),0.0f);
|
||||
song.systemPanFR[index]=c.getFloat(fmt::sprintf("fr%d",index),0.0f);
|
||||
song.systemFlags[index].clear();
|
||||
|
||||
if (oldVol) {
|
||||
song.systemVol[index]/=64.0f;
|
||||
song.systemPan[index]/=127.0f;
|
||||
}
|
||||
|
||||
String flags=c.getString(fmt::sprintf("flags%d",index),"");
|
||||
song.systemFlags[index].loadFromBase64(flags.c_str());
|
||||
}
|
||||
|
@ -1667,14 +1683,36 @@ bool DivEngine::addSystem(DivSystem which) {
|
|||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
song.system[song.systemLen]=which;
|
||||
song.systemVol[song.systemLen]=64;
|
||||
song.systemVol[song.systemLen]=1.0;
|
||||
song.systemPan[song.systemLen]=0;
|
||||
song.systemPanFR[song.systemLen]=0;
|
||||
song.systemFlags[song.systemLen++].clear();
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
if (song.patchbayAuto) {
|
||||
autoPatchbay();
|
||||
} else {
|
||||
int i=song.systemLen-1;
|
||||
if (disCont[i].dispatch!=NULL) {
|
||||
unsigned int outs=disCont[i].dispatch->getOutputCount();
|
||||
if (outs>16) outs=16;
|
||||
if (outs<2) {
|
||||
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||
song.patchbay.push_back((i<<20)|j);
|
||||
}
|
||||
} else {
|
||||
for (unsigned int j=0; j<outs; j++) {
|
||||
|
||||
song.patchbay.push_back((i<<20)|(j<<16)|j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
saveLock.unlock();
|
||||
renderSamples();
|
||||
reset();
|
||||
BUSY_END;
|
||||
|
@ -1707,12 +1745,21 @@ bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
|||
}
|
||||
}
|
||||
|
||||
// patchbay
|
||||
for (size_t i=0; i<song.patchbay.size(); i++) {
|
||||
if (((song.patchbay[i]>>20)&0xfff)==(unsigned int)index) {
|
||||
song.patchbay.erase(song.patchbay.begin()+i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
song.system[index]=DIV_SYSTEM_NULL;
|
||||
song.systemLen--;
|
||||
for (int i=index; i<song.systemLen; i++) {
|
||||
song.system[i]=song.system[i+1];
|
||||
song.systemVol[i]=song.systemVol[i+1];
|
||||
song.systemPan[i]=song.systemPan[i+1];
|
||||
song.systemPanFR[i]=song.systemPanFR[i+1];
|
||||
song.systemFlags[i]=song.systemFlags[i+1];
|
||||
}
|
||||
recalcChans();
|
||||
|
@ -1827,23 +1874,36 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) {
|
|||
}
|
||||
|
||||
DivSystem srcSystem=song.system[src];
|
||||
float srcVol=song.systemVol[src];
|
||||
float srcPan=song.systemPan[src];
|
||||
float srcPanFR=song.systemPanFR[src];
|
||||
|
||||
song.system[src]=song.system[dest];
|
||||
song.system[dest]=srcSystem;
|
||||
|
||||
song.systemVol[src]^=song.systemVol[dest];
|
||||
song.systemVol[dest]^=song.systemVol[src];
|
||||
song.systemVol[src]^=song.systemVol[dest];
|
||||
song.systemVol[src]=song.systemVol[dest];
|
||||
song.systemVol[dest]=srcVol;
|
||||
|
||||
song.systemPan[src]^=song.systemPan[dest];
|
||||
song.systemPan[dest]^=song.systemPan[src];
|
||||
song.systemPan[src]^=song.systemPan[dest];
|
||||
song.systemPan[src]=song.systemPan[dest];
|
||||
song.systemPan[dest]=srcPan;
|
||||
|
||||
song.systemPanFR[src]=song.systemPanFR[dest];
|
||||
song.systemPanFR[dest]=srcPanFR;
|
||||
|
||||
// I am kinda scared to use std::swap
|
||||
DivConfig oldFlags=song.systemFlags[src];
|
||||
song.systemFlags[src]=song.systemFlags[dest];
|
||||
song.systemFlags[dest]=oldFlags;
|
||||
|
||||
// patchbay
|
||||
for (unsigned int& i: song.patchbay) {
|
||||
if (((i>>20)&0xfff)==(unsigned int)src) {
|
||||
i=(i&(~0xfff00000))|((unsigned int)dest<<20);
|
||||
} else if (((i>>20)&0xfff)==(unsigned int)dest) {
|
||||
i=(i&(~0xfff00000))|((unsigned int)src<<20);
|
||||
}
|
||||
}
|
||||
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
@ -1904,10 +1964,11 @@ String DivEngine::getPlaybackDebugInfo() {
|
|||
"speed1: %d\n"
|
||||
"speed2: %d\n"
|
||||
"tempoAccum: %d\n"
|
||||
"totalProcessed: %d\n",
|
||||
"totalProcessed: %d\n"
|
||||
"bufferPos: %d\n",
|
||||
curOrder,prevOrder,curRow,prevRow,ticks,subticks,totalLoops,lastLoopPos,nextSpeed,divider,cycles,clockDrift,
|
||||
changeOrd,changePos,totalSeconds,totalTicks,totalTicksR,totalCmds,lastCmds,cmdsPerSecond,globalPitch,
|
||||
(int)extValue,(int)speed1,(int)speed2,(int)tempoAccum,(int)totalProcessed
|
||||
(int)extValue,(int)speed1,(int)speed2,(int)tempoAccum,(int)totalProcessed,(int)bufferPos
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3750,6 +3811,102 @@ bool DivEngine::moveSampleDown(int which) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DivEngine::autoPatchbay() {
|
||||
song.patchbay.clear();
|
||||
for (unsigned int i=0; i<song.systemLen; i++) {
|
||||
if (disCont[i].dispatch==NULL) continue;
|
||||
|
||||
unsigned int outs=disCont[i].dispatch->getOutputCount();
|
||||
if (outs>16) outs=16;
|
||||
if (outs<2) {
|
||||
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||
song.patchbay.push_back((i<<20)|j);
|
||||
}
|
||||
} else {
|
||||
for (unsigned int j=0; j<outs; j++) {
|
||||
|
||||
song.patchbay.push_back((i<<20)|(j<<16)|j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// wave/sample preview
|
||||
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||
song.patchbay.push_back(0xffd00000|j);
|
||||
}
|
||||
|
||||
// metronome
|
||||
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||
song.patchbay.push_back(0xffe00000|j);
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::autoPatchbayP() {
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
autoPatchbay();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
}
|
||||
|
||||
bool DivEngine::patchConnect(unsigned int src, unsigned int dest) {
|
||||
unsigned int armed=(src<<16)|(dest&0xffff);
|
||||
for (unsigned int i: song.patchbay) {
|
||||
if (i==armed) return false;
|
||||
}
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
song.patchbay.push_back(armed);
|
||||
song.patchbayAuto=false;
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DivEngine::patchDisconnect(unsigned int src, unsigned int dest) {
|
||||
unsigned int armed=(src<<16)|(dest&0xffff);
|
||||
for (auto i=song.patchbay.begin(); i!=song.patchbay.end(); i++) {
|
||||
if (*i==armed) {
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
song.patchbay.erase(i);
|
||||
song.patchbayAuto=false;
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivEngine::patchDisconnectAll(unsigned int portSet) {
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
|
||||
if (portSet&0x1000) {
|
||||
portSet&=0xfff;
|
||||
|
||||
for (size_t i=0; i<song.patchbay.size(); i++) {
|
||||
if ((song.patchbay[i]&0xfff0)==(portSet<<4)) {
|
||||
song.patchbay.erase(song.patchbay.begin()+i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
portSet&=0xfff;
|
||||
|
||||
for (size_t i=0; i<song.patchbay.size(); i++) {
|
||||
if ((song.patchbay[i]&0xfff00000)==(portSet<<20)) {
|
||||
song.patchbay.erase(song.patchbay.begin()+i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
}
|
||||
|
||||
void DivEngine::noteOn(int chan, int ins, int note, int vol) {
|
||||
if (chan<0 || chan>=chans) return;
|
||||
BUSY_BEGIN;
|
||||
|
@ -3889,6 +4046,14 @@ void DivEngine::updateSysFlags(int system, bool restart) {
|
|||
BUSY_BEGIN_SOFT;
|
||||
disCont[system].dispatch->setFlags(song.systemFlags[system]);
|
||||
disCont[system].setRates(got.rate);
|
||||
|
||||
// patchbay
|
||||
if (song.patchbayAuto) {
|
||||
saveLock.lock();
|
||||
autoPatchbay();
|
||||
saveLock.unlock();
|
||||
}
|
||||
|
||||
if (restart && isPlaying()) {
|
||||
playSub(false);
|
||||
}
|
||||
|
@ -4053,6 +4218,11 @@ void DivEngine::initDispatch() {
|
|||
disCont[i].setRates(got.rate);
|
||||
disCont[i].setQuality(lowQuality);
|
||||
}
|
||||
if (song.patchbayAuto) {
|
||||
saveLock.lock();
|
||||
autoPatchbay();
|
||||
saveLock.unlock();
|
||||
}
|
||||
recalcChans();
|
||||
BUSY_END;
|
||||
}
|
||||
|
@ -4151,10 +4321,13 @@ bool DivEngine::initAudioBackend() {
|
|||
want.rate=getConfInt("audioRate",44100);
|
||||
want.fragments=2;
|
||||
want.inChans=0;
|
||||
want.outChans=2;
|
||||
want.outChans=getConfInt("audioChans",2);
|
||||
want.outFormat=TA_AUDIO_FORMAT_F32;
|
||||
want.name="Furnace";
|
||||
|
||||
if (want.outChans<1) want.outChans=1;
|
||||
if (want.outChans>16) want.outChans=16;
|
||||
|
||||
output->setCallback(process,this);
|
||||
|
||||
if (!output->init(want,got)) {
|
||||
|
@ -4165,6 +4338,13 @@ bool DivEngine::initAudioBackend() {
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int i=0; i<got.outChans; i++) {
|
||||
if (oscBuf[i]==NULL) {
|
||||
oscBuf[i]=new float[32768];
|
||||
}
|
||||
memset(oscBuf[i],0,32768*sizeof(float));
|
||||
}
|
||||
|
||||
if (output->initMidi(false)) {
|
||||
midiIns=output->midiIn->listDevices();
|
||||
midiOuts=output->midiOut->listDevices();
|
||||
|
@ -4246,13 +4426,15 @@ bool DivEngine::init() {
|
|||
if (!hasLoadedSomething) {
|
||||
logD("setting default preset");
|
||||
String preset=getConfString("initialSys2","");
|
||||
bool oldVol=getConfInt("configVersion",DIV_ENGINE_VERSION)<135;
|
||||
if (preset.empty()) {
|
||||
// try loading old preset
|
||||
preset=decodeSysDesc(getConfString("initialSys",""));
|
||||
oldVol=false;
|
||||
}
|
||||
logD("preset size %ld",preset.size());
|
||||
if (preset.size()>0 && (preset.size()&3)==0) {
|
||||
initSongWithDesc(preset.c_str());
|
||||
initSongWithDesc(preset.c_str(),true,oldVol);
|
||||
}
|
||||
String sysName=getConfString("initialSysName","");
|
||||
if (sysName=="") {
|
||||
|
@ -4282,6 +4464,9 @@ bool DivEngine::init() {
|
|||
samp_bbIn=new short[32768];
|
||||
samp_bbInLen=32768;
|
||||
|
||||
metroBuf=new float[8192];
|
||||
metroBufLen=8192;
|
||||
|
||||
blip_set_rates(samp_bb,44100,got.rate);
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
|
@ -4297,12 +4482,6 @@ bool DivEngine::init() {
|
|||
keyHit[i]=false;
|
||||
}
|
||||
|
||||
oscBuf[0]=new float[32768];
|
||||
oscBuf[1]=new float[32768];
|
||||
|
||||
memset(oscBuf[0],0,32768*sizeof(float));
|
||||
memset(oscBuf[1],0,32768*sizeof(float));
|
||||
|
||||
initDispatch();
|
||||
renderSamples();
|
||||
reset();
|
||||
|
@ -4311,6 +4490,10 @@ bool DivEngine::init() {
|
|||
if (!haveAudio) {
|
||||
return false;
|
||||
} else {
|
||||
if (output==NULL) {
|
||||
logE("output is NULL!");
|
||||
return false;
|
||||
}
|
||||
if (!output->setRun(true)) {
|
||||
logE("error while activating!");
|
||||
return false;
|
||||
|
@ -4325,8 +4508,14 @@ bool DivEngine::quit() {
|
|||
logI("saving config.");
|
||||
saveConf();
|
||||
active=false;
|
||||
delete[] oscBuf[0];
|
||||
delete[] oscBuf[1];
|
||||
for (int i=0; i<DIV_MAX_OUTPUTS; i++) {
|
||||
if (oscBuf[i]!=NULL) delete[] oscBuf[i];
|
||||
}
|
||||
if (metroBuf!=NULL) {
|
||||
delete[] metroBuf;
|
||||
metroBuf=NULL;
|
||||
metroBufLen=0;
|
||||
}
|
||||
if (yrw801ROM!=NULL) delete[] yrw801ROM;
|
||||
if (tg100ROM!=NULL) delete[] tg100ROM;
|
||||
if (mu5ROM!=NULL) delete[] mu5ROM;
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||
|
||||
#define DIV_VERSION "0.6pre3"
|
||||
#define DIV_ENGINE_VERSION 133
|
||||
#define DIV_VERSION "dev136"
|
||||
#define DIV_ENGINE_VERSION 136
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
@ -97,7 +97,7 @@ struct DivChannelState {
|
|||
int delayOrder, delayRow, retrigSpeed, retrigTick;
|
||||
int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoDir, vibratoFine;
|
||||
int tremoloDepth, tremoloRate, tremoloPos;
|
||||
unsigned char arp, arpStage, arpTicks, panL, panR;
|
||||
unsigned char arp, arpStage, arpTicks, panL, panR, panRL, panRR;
|
||||
bool doNote, legato, portaStop, keyOn, keyOff, nowYouCanStop, stopOnOff;
|
||||
bool arpYield, delayLocked, inPorta, scheduledSlideReset, shorthandPorta, wasShorthandPorta, noteOnInhibit, resetArp;
|
||||
|
||||
|
@ -135,6 +135,8 @@ struct DivChannelState {
|
|||
arpTicks(1),
|
||||
panL(255),
|
||||
panR(255),
|
||||
panRL(0),
|
||||
panRR(0),
|
||||
doNote(false),
|
||||
legato(false),
|
||||
portaStop(false),
|
||||
|
@ -170,15 +172,18 @@ struct DivNoteEvent {
|
|||
|
||||
struct DivDispatchContainer {
|
||||
DivDispatch* dispatch;
|
||||
blip_buffer_t* bb[2];
|
||||
blip_buffer_t* bb[DIV_MAX_OUTPUTS];
|
||||
size_t bbInLen, runtotal, runLeft, runPos, lastAvail;
|
||||
int temp[2], prevSample[2];
|
||||
short* bbIn[2];
|
||||
short* bbOut[2];
|
||||
int temp[DIV_MAX_OUTPUTS], prevSample[DIV_MAX_OUTPUTS];
|
||||
short* bbInMapped[DIV_MAX_OUTPUTS];
|
||||
short* bbIn[DIV_MAX_OUTPUTS];
|
||||
short* bbOut[DIV_MAX_OUTPUTS];
|
||||
bool lowQuality, dcOffCompensation;
|
||||
double rateMemory;
|
||||
|
||||
void setRates(double gotRate);
|
||||
void setQuality(bool lowQual);
|
||||
void grow(size_t size);
|
||||
void acquire(size_t offset, size_t count);
|
||||
void flush(size_t count);
|
||||
void fillBuf(size_t runtotal, size_t offset, size_t size);
|
||||
|
@ -187,18 +192,21 @@ struct DivDispatchContainer {
|
|||
void quit();
|
||||
DivDispatchContainer():
|
||||
dispatch(NULL),
|
||||
bb{NULL,NULL},
|
||||
bbInLen(0),
|
||||
runtotal(0),
|
||||
runLeft(0),
|
||||
runPos(0),
|
||||
lastAvail(0),
|
||||
temp{0,0},
|
||||
prevSample{0,0},
|
||||
bbIn{NULL,NULL},
|
||||
bbOut{NULL,NULL},
|
||||
lowQuality(false),
|
||||
dcOffCompensation(false) {}
|
||||
dcOffCompensation(false),
|
||||
rateMemory(0.0) {
|
||||
memset(bb,0,DIV_MAX_OUTPUTS*sizeof(blip_buffer_t*));
|
||||
memset(temp,0,DIV_MAX_OUTPUTS*sizeof(int));
|
||||
memset(prevSample,0,DIV_MAX_OUTPUTS*sizeof(int));
|
||||
memset(bbIn,0,DIV_MAX_OUTPUTS*sizeof(short*));
|
||||
memset(bbInMapped,0,DIV_MAX_OUTPUTS*sizeof(short*));
|
||||
memset(bbOut,0,DIV_MAX_OUTPUTS*sizeof(short*));
|
||||
}
|
||||
};
|
||||
|
||||
typedef int EffectValConversion(unsigned char,unsigned char);
|
||||
|
@ -353,6 +361,7 @@ class DivEngine {
|
|||
int softLockCount;
|
||||
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed, elapsedBars, elapsedBeats;
|
||||
size_t curSubSongIndex;
|
||||
size_t bufferPos;
|
||||
double divider;
|
||||
int cycles;
|
||||
double clockDrift;
|
||||
|
@ -418,6 +427,8 @@ class DivEngine {
|
|||
short* samp_bbOut;
|
||||
unsigned char* metroTick;
|
||||
size_t metroTickLen;
|
||||
float* metroBuf;
|
||||
size_t metroBufLen;
|
||||
float metroFreq, metroPos;
|
||||
float metroAmp;
|
||||
float metroVol;
|
||||
|
@ -467,7 +478,7 @@ class DivEngine {
|
|||
bool deinitAudioBackend(bool dueToSwitchMaster=false);
|
||||
|
||||
void registerSystems();
|
||||
void initSongWithDesc(const char* description, bool inBase64=true);
|
||||
void initSongWithDesc(const char* description, bool inBase64=true, bool oldVol=false);
|
||||
|
||||
void exchangeIns(int one, int two);
|
||||
void swapChannels(int src, int dest);
|
||||
|
@ -486,7 +497,7 @@ class DivEngine {
|
|||
int dispatchOfChan[DIV_MAX_CHANS];
|
||||
int dispatchChanOfChan[DIV_MAX_CHANS];
|
||||
bool keyHit[DIV_MAX_CHANS];
|
||||
float* oscBuf[2];
|
||||
float* oscBuf[DIV_MAX_OUTPUTS];
|
||||
float oscSize;
|
||||
int oscReadPos, oscWritePos;
|
||||
int tickMult;
|
||||
|
@ -826,6 +837,21 @@ class DivEngine {
|
|||
bool moveWaveDown(int which);
|
||||
bool moveSampleDown(int which);
|
||||
|
||||
// automatic patchbay
|
||||
void autoPatchbay();
|
||||
void autoPatchbayP();
|
||||
|
||||
// connect in patchbay
|
||||
// returns false if connection already made
|
||||
bool patchConnect(unsigned int src, unsigned int dest);
|
||||
|
||||
// disconnect in patchbay
|
||||
// returns false if connection doesn't exist
|
||||
bool patchDisconnect(unsigned int src, unsigned int dest);
|
||||
|
||||
// disconnect all in patchbay
|
||||
void patchDisconnectAll(unsigned int portSet);
|
||||
|
||||
// play note
|
||||
void noteOn(int chan, int ins, int note, int vol=-1);
|
||||
|
||||
|
@ -902,6 +928,9 @@ class DivEngine {
|
|||
// set metronome volume (1.0 = 100%)
|
||||
void setMetronomeVol(float vol);
|
||||
|
||||
// get buffer position
|
||||
int getBufferPos();
|
||||
|
||||
// halt now
|
||||
void halt();
|
||||
|
||||
|
@ -1070,6 +1099,7 @@ class DivEngine {
|
|||
elapsedBars(0),
|
||||
elapsedBeats(0),
|
||||
curSubSongIndex(0),
|
||||
bufferPos(0),
|
||||
divider(60),
|
||||
cycles(0),
|
||||
clockDrift(0),
|
||||
|
@ -1104,6 +1134,8 @@ class DivEngine {
|
|||
samp_bbOut(NULL),
|
||||
metroTick(NULL),
|
||||
metroTickLen(0),
|
||||
metroBuf(NULL),
|
||||
metroBufLen(0),
|
||||
metroFreq(0),
|
||||
metroPos(0),
|
||||
metroAmp(0.0f),
|
||||
|
@ -1112,7 +1144,6 @@ class DivEngine {
|
|||
curOrders(NULL),
|
||||
curPat(NULL),
|
||||
tempIns(NULL),
|
||||
oscBuf{NULL,NULL},
|
||||
oscSize(1),
|
||||
oscReadPos(0),
|
||||
oscWritePos(0),
|
||||
|
@ -1131,6 +1162,7 @@ class DivEngine {
|
|||
memset(pitchTable,0,4096*sizeof(int));
|
||||
memset(sysDefs,0,256*sizeof(void*));
|
||||
memset(walked,0,8192);
|
||||
memset(oscBuf,0,DIV_MAX_OUTPUTS*(sizeof(float*)));
|
||||
|
||||
for (int i=0; i<256; i++) {
|
||||
sysFileMapFur[i]=DIV_SYSTEM_NULL;
|
||||
|
|
|
@ -939,13 +939,13 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.systemLen=2;
|
||||
ds.system[0]=DIV_SYSTEM_YM2612;
|
||||
ds.system[1]=DIV_SYSTEM_SMS;
|
||||
ds.systemVol[1]=32;
|
||||
ds.systemVol[1]=0.5f;
|
||||
}
|
||||
if (ds.system[0]==DIV_SYSTEM_GENESIS_EXT) {
|
||||
ds.systemLen=2;
|
||||
ds.system[0]=DIV_SYSTEM_YM2612_EXT;
|
||||
ds.system[1]=DIV_SYSTEM_SMS;
|
||||
ds.systemVol[1]=32;
|
||||
ds.systemVol[1]=0.5f;
|
||||
}
|
||||
if (ds.system[0]==DIV_SYSTEM_ARCADE) {
|
||||
ds.systemLen=2;
|
||||
|
@ -1830,14 +1830,18 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
|
||||
// system volume
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
ds.systemVol[i]=reader.readC();
|
||||
signed char oldSysVol=reader.readC();
|
||||
ds.systemVol[i]=(float)oldSysVol/64.0f;
|
||||
if (ds.version<59 && ds.system[i]==DIV_SYSTEM_NES) {
|
||||
ds.systemVol[i]/=4;
|
||||
}
|
||||
}
|
||||
|
||||
// system panning
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) ds.systemPan[i]=reader.readC();
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
signed char oldSysPan=reader.readC();
|
||||
ds.systemPan[i]=(float)oldSysPan/127.0f;
|
||||
}
|
||||
|
||||
// system props
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
|
@ -1860,14 +1864,14 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
ds.system[i]=DIV_SYSTEM_YM2612;
|
||||
if (i<31) {
|
||||
ds.system[i+1]=DIV_SYSTEM_SMS;
|
||||
ds.systemVol[i+1]=(((ds.systemVol[i]&127)*3)>>3)|(ds.systemVol[i]&128);
|
||||
ds.systemVol[i+1]=ds.systemVol[i]*0.375f;
|
||||
}
|
||||
}
|
||||
if (ds.system[i]==DIV_SYSTEM_GENESIS_EXT) {
|
||||
ds.system[i]=DIV_SYSTEM_YM2612_EXT;
|
||||
if (i<31) {
|
||||
ds.system[i+1]=DIV_SYSTEM_SMS;
|
||||
ds.systemVol[i+1]=(((ds.systemVol[i]&127)*3)>>3)|(ds.systemVol[i]&128);
|
||||
ds.systemVol[i+1]=ds.systemVol[i]*0.375f;
|
||||
}
|
||||
}
|
||||
if (ds.system[i]==DIV_SYSTEM_ARCADE) {
|
||||
|
@ -2200,6 +2204,23 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
ds.autoSystem=true;
|
||||
}
|
||||
|
||||
// system output config
|
||||
if (ds.version>=135) {
|
||||
for (int i=0; i<ds.systemLen; i++) {
|
||||
ds.systemVol[i]=reader.readF();
|
||||
ds.systemPan[i]=reader.readF();
|
||||
ds.systemPanFR[i]=reader.readF();
|
||||
}
|
||||
|
||||
// patchbay
|
||||
unsigned int conns=reader.readI();
|
||||
for (unsigned int i=0; i<conns; i++) {
|
||||
ds.patchbay.push_back((unsigned int)reader.readI());
|
||||
}
|
||||
}
|
||||
|
||||
if (ds.version>=136) song.patchbayAuto=reader.readC();
|
||||
|
||||
// read system flags
|
||||
if (ds.version>=119) {
|
||||
logD("reading chip flags...");
|
||||
|
@ -2543,6 +2564,16 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
// OPL3 pan compat
|
||||
if (ds.version<134) {
|
||||
for (int i=0; i<ds.systemLen; i++) {
|
||||
if (ds.system[i]==DIV_SYSTEM_OPL3 ||
|
||||
ds.system[i]==DIV_SYSTEM_OPL3_DRUMS) {
|
||||
ds.systemFlags[i].set("compatPan",true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
|
@ -3147,7 +3178,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
|
||||
ds.systemLen=1;
|
||||
ds.system[0]=DIV_SYSTEM_AMIGA;
|
||||
ds.systemVol[0]=64;
|
||||
ds.systemVol[0]=1.0f;
|
||||
ds.systemPan[0]=0;
|
||||
ds.systemFlags[0].set("clockSel",1); // PAL
|
||||
ds.systemFlags[0].set("stereoSep",80);
|
||||
|
@ -4298,11 +4329,11 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
}
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
w->writeC(song.systemVol[i]);
|
||||
w->writeC(song.systemVol[i]*64.0f);
|
||||
}
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
w->writeC(song.systemPan[i]);
|
||||
w->writeC(song.systemPan[i]*127.0f);
|
||||
}
|
||||
|
||||
// chip flags (we'll seek here later)
|
||||
|
@ -4446,6 +4477,18 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeString(song.systemNameJ,false);
|
||||
w->writeString(song.categoryJ,false);
|
||||
|
||||
// system output config
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
w->writeF(song.systemVol[i]);
|
||||
w->writeF(song.systemPan[i]);
|
||||
w->writeF(song.systemPanFR[i]);
|
||||
}
|
||||
w->writeI(song.patchbay.size());
|
||||
for (unsigned int i: song.patchbay) {
|
||||
w->writeI(i);
|
||||
}
|
||||
w->writeC(song.patchbayAuto);
|
||||
|
||||
blockEndSeek=w->tell();
|
||||
w->seek(blockStartSeek,SEEK_SET);
|
||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "../dispatch.h"
|
||||
|
||||
void DivDispatch::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivDispatch::acquire(short** buf, size_t len) {
|
||||
}
|
||||
|
||||
void DivDispatch::fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len) {
|
||||
|
@ -69,8 +69,8 @@ int DivDispatch::dispatch(DivCommand c) {
|
|||
void DivDispatch::reset() {
|
||||
}
|
||||
|
||||
bool DivDispatch::isStereo() {
|
||||
return false;
|
||||
int DivDispatch::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool DivDispatch::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -75,9 +75,9 @@ const char** DivPlatformAmiga::getRegisterSheet() {
|
|||
if (chan[i+1].freq<AMIGA_DIVIDER) chan[i+1].freq=AMIGA_DIVIDER; \
|
||||
}
|
||||
|
||||
void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformAmiga::acquire(short** buf, size_t len) {
|
||||
static int outL, outR, output;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
outL=0;
|
||||
outR=0;
|
||||
for (int i=0; i<4; i++) {
|
||||
|
@ -142,8 +142,8 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le
|
|||
filter[0][1]+=(filtConst*(filter[0][0]-filter[0][1]))>>12;
|
||||
filter[1][0]+=(filtConst*(outR-filter[1][0]))>>12;
|
||||
filter[1][1]+=(filtConst*(filter[1][0]-filter[1][1]))>>12;
|
||||
bufL[h]=filter[0][1];
|
||||
bufR[h]=filter[1][1];
|
||||
buf[0][h]=filter[0][1];
|
||||
buf[1][h]=filter[1][1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,8 +401,8 @@ void DivPlatformAmiga::reset() {
|
|||
filtConst=filterOn?filtConstOn:filtConstOff;
|
||||
}
|
||||
|
||||
bool DivPlatformAmiga::isStereo() {
|
||||
return true;
|
||||
int DivPlatformAmiga::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformAmiga::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class DivPlatformAmiga: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -75,7 +75,7 @@ class DivPlatformAmiga: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "arcade.h"
|
||||
#include "../engine.h"
|
||||
#include "../../ta-log.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
|
@ -50,10 +51,10 @@ const char** DivPlatformArcade::getRegisterSheet() {
|
|||
return regCheatSheetOPM;
|
||||
}
|
||||
|
||||
void DivPlatformArcade::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformArcade::acquire_nuked(short** buf, size_t len) {
|
||||
static int o[2];
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
for (int i=0; i<8; i++) {
|
||||
if (!writes.empty() && !fm.write_busy) {
|
||||
QueuedWrite& w=writes.front();
|
||||
|
@ -84,17 +85,17 @@ void DivPlatformArcade::acquire_nuked(short* bufL, short* bufR, size_t start, si
|
|||
if (o[1]<-32768) o[1]=-32768;
|
||||
if (o[1]>32767) o[1]=32767;
|
||||
|
||||
bufL[h]=o[0];
|
||||
bufR[h]=o[1];
|
||||
buf[0][h]=o[0];
|
||||
buf[1][h]=o[1];
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformArcade::acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformArcade::acquire_ymfm(short** buf, size_t len) {
|
||||
static int os[2];
|
||||
|
||||
ymfm::ym2151::fm_engine* fme=fm_ymfm->debug_engine();
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
os[0]=0; os[1]=0;
|
||||
if (!writes.empty()) {
|
||||
if (--delay<1) {
|
||||
|
@ -121,16 +122,16 @@ void DivPlatformArcade::acquire_ymfm(short* bufL, short* bufR, size_t start, siz
|
|||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
bufL[h]=os[0];
|
||||
bufR[h]=os[1];
|
||||
buf[0][h]=os[0];
|
||||
buf[1][h]=os[1];
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformArcade::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformArcade::acquire(short** buf, size_t len) {
|
||||
if (useYMFM) {
|
||||
acquire_ymfm(bufL,bufR,start,len);
|
||||
acquire_ymfm(buf,len);
|
||||
} else {
|
||||
acquire_nuked(bufL,bufR,start,len);
|
||||
acquire_nuked(buf,len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -868,25 +869,26 @@ void DivPlatformArcade::setFlags(const DivConfig& flags) {
|
|||
switch (flags.getInt("clockSel",0)) {
|
||||
case 1:
|
||||
chipClock=COLOR_PAL*4.0/5.0;
|
||||
baseFreqOff=12;
|
||||
break;
|
||||
case 2:
|
||||
chipClock=4000000.0;
|
||||
baseFreqOff=-122;
|
||||
break;
|
||||
default:
|
||||
chipClock=COLOR_NTSC;
|
||||
baseFreqOff=0;
|
||||
break;
|
||||
}
|
||||
CHECK_CUSTOM_CLOCK;
|
||||
|
||||
baseFreqOff=round(768.0*(log((COLOR_NTSC/(double)chipClock))/log(2.0)));
|
||||
|
||||
rate=chipClock/64;
|
||||
for (int i=0; i<8; i++) {
|
||||
oscBuf[i]->rate=rate;
|
||||
}
|
||||
}
|
||||
|
||||
bool DivPlatformArcade::isStereo() {
|
||||
return true;
|
||||
int DivPlatformArcade::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void DivPlatformArcade::setYMFM(bool use) {
|
||||
|
|
|
@ -58,13 +58,13 @@ class DivPlatformArcade: public DivPlatformOPM {
|
|||
int octave(int freq);
|
||||
int toFreq(int freq);
|
||||
|
||||
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_nuked(short** buf, size_t len);
|
||||
void acquire_ymfm(short** buf, size_t len);
|
||||
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
friend void putDispatchChip(void*,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -77,7 +77,7 @@ class DivPlatformArcade: public DivPlatformOPM {
|
|||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void notifyInsChange(int ins);
|
||||
void setFlags(const DivConfig& flags);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void setYMFM(bool use);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
|
|
|
@ -169,7 +169,7 @@ void DivPlatformAY8910::checkWrites() {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformAY8910::acquire(short** buf, size_t len) {
|
||||
if (ayBufLen<len) {
|
||||
ayBufLen=len;
|
||||
for (int i=0; i<3; i++) {
|
||||
|
@ -184,8 +184,8 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
checkWrites();
|
||||
|
||||
ay->sound_stream_update(ayBuf,1);
|
||||
bufL[i+start]=ayBuf[0][0];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
buf[0][i]=ayBuf[0][0];
|
||||
buf[1][i]=buf[0][i];
|
||||
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=sunsoftVolTable[31-(ay->lastIndx&31)]>>3;
|
||||
oscBuf[1]->data[oscBuf[1]->needle++]=sunsoftVolTable[31-((ay->lastIndx>>5)&31)]>>3;
|
||||
|
@ -198,11 +198,11 @@ void DivPlatformAY8910::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
|
||||
ay->sound_stream_update(ayBuf,1);
|
||||
if (stereo) {
|
||||
bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8);
|
||||
bufR[i+start]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0];
|
||||
buf[0][i]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8);
|
||||
buf[1][i]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0];
|
||||
} else {
|
||||
bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
buf[0][i]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0];
|
||||
buf[1][i]=buf[0][i];
|
||||
}
|
||||
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2;
|
||||
|
@ -337,6 +337,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
chan[i].dac.rate=((double)rate*((sunsoft||clockSel)?8.0:16.0))/(double)(MAX(1,off*chan[i].freq));
|
||||
if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dac.rate);
|
||||
}
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
if (chan[i].keyOn) {
|
||||
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
|
||||
|
@ -751,8 +752,8 @@ void DivPlatformAY8910::reset() {
|
|||
portBVal=0;
|
||||
}
|
||||
|
||||
bool DivPlatformAY8910::isStereo() {
|
||||
return true;
|
||||
int DivPlatformAY8910::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformAY8910::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -128,7 +128,7 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
|
||||
public:
|
||||
void setExtClockDiv(unsigned int eclk=COLOR_NTSC, unsigned char ediv=8);
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -140,7 +140,7 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
void setFlags(const DivConfig& flags);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
bool getDCOffRequired();
|
||||
|
|
|
@ -164,7 +164,7 @@ void DivPlatformAY8930::checkWrites() {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformAY8930::acquire(short** buf, size_t len) {
|
||||
if (ayBufLen<len) {
|
||||
ayBufLen=len;
|
||||
for (int i=0; i<3; i++) {
|
||||
|
@ -179,11 +179,11 @@ void DivPlatformAY8930::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
|
||||
ay->sound_stream_update(ayBuf,1);
|
||||
if (stereo) {
|
||||
bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8);
|
||||
bufR[i+start]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0];
|
||||
buf[0][i]=ayBuf[0][0]+ayBuf[1][0]+((ayBuf[2][0]*stereoSep)>>8);
|
||||
buf[1][i]=((ayBuf[0][0]*stereoSep)>>8)+ayBuf[1][0]+ayBuf[2][0];
|
||||
} else {
|
||||
bufL[i+start]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0];
|
||||
bufR[i+start]=bufL[i+start];
|
||||
buf[0][i]=ayBuf[0][0]+ayBuf[1][0]+ayBuf[2][0];
|
||||
buf[1][i]=buf[0][i];
|
||||
}
|
||||
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=ayBuf[0][0]<<2;
|
||||
|
@ -270,7 +270,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||
CLAMP_VAR(chan[i].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (chan[i].std.ex1.had) { // duty
|
||||
rWrite(0x16+i,chan[i].std.ex1.val);
|
||||
immWrite(0x16+i,chan[i].std.ex1.val);
|
||||
}
|
||||
if (chan[i].std.ex2.had) {
|
||||
chan[i].envelope.mode=chan[i].std.ex2.val;
|
||||
|
@ -336,6 +336,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
chan[i].dac.rate=((double)chipClock*4.0)/(double)(MAX(1,off*chan[i].freq));
|
||||
if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dac.rate);
|
||||
}
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].keyOn) {
|
||||
if (!chan[i].nextPSGMode.dac) {
|
||||
|
@ -747,8 +748,8 @@ void DivPlatformAY8930::reset() {
|
|||
immWrite(0x1a,0x00); // or mask
|
||||
}
|
||||
|
||||
bool DivPlatformAY8930::isStereo() {
|
||||
return true;
|
||||
int DivPlatformAY8930::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformAY8930::keyOffAffectsArp(int ch) {
|
||||
|
@ -808,6 +809,12 @@ void DivPlatformAY8930::setFlags(const DivConfig& flags) {
|
|||
case 12:
|
||||
chipClock=3600000;
|
||||
break;
|
||||
case 13:
|
||||
chipClock=20000000/16;
|
||||
break;
|
||||
case 14:
|
||||
chipClock=1536000;
|
||||
break;
|
||||
default:
|
||||
chipClock=COLOR_NTSC/2.0;
|
||||
break;
|
||||
|
|
|
@ -131,7 +131,7 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -142,7 +142,7 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
void setFlags(const DivConfig& flags);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -39,9 +39,9 @@ const char** DivPlatformBubSysWSG::getRegisterSheet() {
|
|||
return regCheatSheetBubSysWSG;
|
||||
}
|
||||
|
||||
void DivPlatformBubSysWSG::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformBubSysWSG::acquire(short** buf, size_t len) {
|
||||
int chanOut=0;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
signed int out=0;
|
||||
// K005289 part
|
||||
k005289.tick();
|
||||
|
@ -68,7 +68,7 @@ void DivPlatformBubSysWSG::acquire(short* bufL, short* bufR, size_t start, size_
|
|||
if (out>32767) out=32767;
|
||||
|
||||
//printf("out: %d\n",out);
|
||||
bufL[h]=bufR[h]=out;
|
||||
buf[0][h]=out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,8 +306,8 @@ void DivPlatformBubSysWSG::reset() {
|
|||
k005289.reset();
|
||||
}
|
||||
|
||||
bool DivPlatformBubSysWSG::isStereo() {
|
||||
return false;
|
||||
int DivPlatformBubSysWSG::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool DivPlatformBubSysWSG::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class DivPlatformBubSysWSG: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -56,7 +56,7 @@ class DivPlatformBubSysWSG: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
|
|
|
@ -63,9 +63,9 @@ const char** DivPlatformC64::getRegisterSheet() {
|
|||
return regCheatSheetSID;
|
||||
}
|
||||
|
||||
void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformC64::acquire(short** buf, size_t len) {
|
||||
int dcOff=isFP?0:sid.get_dc(0);
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
if (isFP) {
|
||||
|
@ -77,7 +77,7 @@ void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
writes.pop();
|
||||
}
|
||||
if (isFP) {
|
||||
sid_fp.clock(4,&bufL[i]);
|
||||
sid_fp.clock(4,&buf[0][i]);
|
||||
if (++writeOscBuf>=4) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=(sid_fp.lastChanOut[0]-dcOff)>>5;
|
||||
|
@ -86,7 +86,7 @@ void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
}
|
||||
} else {
|
||||
sid.clock();
|
||||
bufL[i]=sid.output();
|
||||
buf[0][i]=sid.output();
|
||||
if (++writeOscBuf>=16) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=(sid.last_chan_out[0]-dcOff)>>5;
|
||||
|
@ -148,7 +148,7 @@ void DivPlatformC64::tick(bool sysTick) {
|
|||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||
CLAMP_VAR(chan[i].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
|
@ -188,6 +188,7 @@ void DivPlatformC64::tick(bool sysTick) {
|
|||
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,8,chan[i].pitch2,chipClock,CHIP_FREQBASE);
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq>0xffff) chan[i].freq=0xffff;
|
||||
if (chan[i].keyOn) {
|
||||
rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay));
|
||||
|
|
|
@ -79,7 +79,7 @@ class DivPlatformC64: public DivDispatch {
|
|||
|
||||
void updateFilter();
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
#define CHIP_FREQBASE 2048
|
||||
|
||||
void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformDummy::acquire(short** buf, size_t len) {
|
||||
int chanOut;
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
int out=0;
|
||||
for (unsigned char j=0; j<chans; j++) {
|
||||
if (chan[j].active) {
|
||||
|
@ -44,7 +44,7 @@ void DivPlatformDummy::acquire(short* bufL, short* bufR, size_t start, size_t le
|
|||
}
|
||||
if (out<-32768) out=-32768;
|
||||
if (out>32767) out=32767;
|
||||
bufL[i]=out;
|
||||
buf[0][i]=out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class DivPlatformDummy: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
void muteChannel(int ch, bool mute);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
|
|
|
@ -55,13 +55,13 @@ const char** DivPlatformFDS::getRegisterSheet() {
|
|||
return regCheatSheetFDS;
|
||||
}
|
||||
|
||||
void DivPlatformFDS::acquire_puNES(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformFDS::acquire_puNES(short* buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
extcl_apu_tick_FDS(fds);
|
||||
int sample=isMuted[0]?0:fds->snd.main.output;
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
bufL[i]=sample;
|
||||
buf[i]=sample;
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
oscBuf->data[oscBuf->needle++]=sample<<1;
|
||||
|
@ -69,15 +69,15 @@ void DivPlatformFDS::acquire_puNES(short* bufL, short* bufR, size_t start, size_
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformFDS::acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformFDS::acquire_NSFPlay(short* buf, size_t len) {
|
||||
int out[2];
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
fds_NP->Tick(1);
|
||||
fds_NP->Render(out);
|
||||
int sample=isMuted[0]?0:(out[0]<<1);
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
bufL[i]=sample;
|
||||
buf[i]=sample;
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
oscBuf->data[oscBuf->needle++]=sample<<1;
|
||||
|
@ -93,11 +93,11 @@ void DivPlatformFDS::doWrite(unsigned short addr, unsigned char data) {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformFDS::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformFDS::acquire(short** buf, size_t len) {
|
||||
if (useNP) {
|
||||
acquire_NSFPlay(bufL,bufR,start,len);
|
||||
acquire_NSFPlay(buf[0],len);
|
||||
} else {
|
||||
acquire_puNES(bufL,bufR,start,len);
|
||||
acquire_puNES(buf[0],len);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,11 +62,11 @@ class DivPlatformFDS: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void doWrite(unsigned short addr, unsigned char data);
|
||||
void acquire_puNES(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_puNES(short* buf, size_t len);
|
||||
void acquire_NSFPlay(short* buf, size_t len);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -51,7 +51,7 @@ inline void DivPlatformGA20::chWrite(unsigned char ch, unsigned int addr, unsign
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformGA20::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformGA20::acquire(short** buf, size_t len) {
|
||||
if (ga20BufLen<len) {
|
||||
ga20BufLen=len;
|
||||
for (int i=0; i<4; i++) {
|
||||
|
@ -60,7 +60,7 @@ void DivPlatformGA20::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
}
|
||||
}
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if ((--delay)<=0) {
|
||||
delay=MAX(0,delay);
|
||||
if (!writes.empty()) {
|
||||
|
@ -73,7 +73,7 @@ void DivPlatformGA20::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
}
|
||||
short *buffer[4] = {&ga20Buf[0][h],&ga20Buf[1][h],&ga20Buf[2][h],&ga20Buf[3][h]};
|
||||
ga20.sound_stream_update(buffer, 1);
|
||||
bufL[h]=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
|
||||
buf[0][h]=(signed int)(ga20Buf[0][h]+ga20Buf[1][h]+ga20Buf[2][h]+ga20Buf[3][h])>>2;
|
||||
for (int i=0; i<4; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=ga20Buf[i][h];
|
||||
}
|
||||
|
@ -361,8 +361,8 @@ void DivPlatformGA20::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformGA20::isStereo() {
|
||||
return false;
|
||||
int DivPlatformGA20::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DivPlatformGA20::notifyInsChange(int ins) {
|
||||
|
|
|
@ -74,7 +74,7 @@ class DivPlatformGA20: public DivDispatch, public iremga20_intf {
|
|||
void chWrite(unsigned char ch, unsigned int addr, unsigned char val);
|
||||
public:
|
||||
virtual u8 read_byte(u32 address) override;
|
||||
virtual void acquire(short* bufL, short* bufR, size_t start, size_t len) override;
|
||||
virtual void acquire(short** buf, size_t len) override;
|
||||
virtual int dispatch(DivCommand c) override;
|
||||
virtual void* getChanState(int chan) override;
|
||||
virtual DivMacroInt* getChanMacroInt(int ch) override;
|
||||
|
@ -85,7 +85,7 @@ class DivPlatformGA20: public DivDispatch, public iremga20_intf {
|
|||
virtual void forceIns() override;
|
||||
virtual void tick(bool sysTick=true) override;
|
||||
virtual void muteChannel(int ch, bool mute) override;
|
||||
virtual bool isStereo() override;
|
||||
virtual int getOutputCount() override;
|
||||
virtual void notifyInsChange(int ins) override;
|
||||
virtual void notifyWaveChange(int wave) override;
|
||||
virtual void notifyInsDeletion(void* ins) override;
|
||||
|
|
|
@ -61,8 +61,8 @@ const char** DivPlatformGB::getRegisterSheet() {
|
|||
return regCheatSheetGB;
|
||||
}
|
||||
|
||||
void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformGB::acquire(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (!writes.empty()) {
|
||||
QueuedWrite& w=writes.front();
|
||||
GB_apu_write(gb,w.addr,w.val);
|
||||
|
@ -70,8 +70,8 @@ void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
}
|
||||
|
||||
GB_advance_cycles(gb,16);
|
||||
bufL[i]=gb->apu_output.final_sample.left;
|
||||
bufR[i]=gb->apu_output.final_sample.right;
|
||||
buf[0][i]=gb->apu_output.final_sample.left;
|
||||
buf[1][i]=gb->apu_output.final_sample.right;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=(gb->apu_output.current_sample[i].left+gb->apu_output.current_sample[i].right)<<6;
|
||||
|
@ -284,14 +284,14 @@ void DivPlatformGB::tick(bool sysTick) {
|
|||
|
||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
if (i==3) { // noise
|
||||
int ntPos=chan[i].baseFreq;
|
||||
int ntPos=chan[i].baseFreq+chan[i].pitch2;
|
||||
if (ntPos<0) ntPos=0;
|
||||
if (ntPos>255) ntPos=255;
|
||||
chan[i].freq=noiseTable[ntPos];
|
||||
} else {
|
||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
|
||||
if (chan[i].freq>2047) chan[i].freq=2047;
|
||||
if (chan[i].freq<0) chan[i].freq=0;
|
||||
if (chan[i].freq<1) chan[i].freq=1;
|
||||
}
|
||||
if (chan[i].keyOn) {
|
||||
if (i==2) { // wave
|
||||
|
@ -604,8 +604,8 @@ int DivPlatformGB::getPortaFloor(int ch) {
|
|||
return 24;
|
||||
}
|
||||
|
||||
bool DivPlatformGB::isStereo() {
|
||||
return true;
|
||||
int DivPlatformGB::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformGB::getDCOffRequired() {
|
||||
|
|
|
@ -78,7 +78,7 @@ class DivPlatformGB: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -90,7 +90,7 @@ class DivPlatformGB: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
int getPortaFloor(int ch);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool getDCOffRequired();
|
||||
void notifyInsChange(int ins);
|
||||
void notifyWaveChange(int wave);
|
||||
|
|
|
@ -132,11 +132,11 @@ void DivPlatformGenesis::processDAC(int iRate) {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
|
||||
static short o[2];
|
||||
static int os[2];
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
processDAC(rate);
|
||||
|
||||
os[0]=0; os[1]=0;
|
||||
|
@ -186,17 +186,17 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s
|
|||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
bufL[h]=os[0];
|
||||
bufR[h]=os[1];
|
||||
buf[0][h]=os[0];
|
||||
buf[1][h]=os[1];
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformGenesis::acquire_ymfm(short** buf, size_t len) {
|
||||
static int os[2];
|
||||
|
||||
ymfm::ym2612::fm_engine* fme=fm_ymfm->debug_engine();
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
processDAC(rate);
|
||||
|
||||
os[0]=0; os[1]=0;
|
||||
|
@ -242,16 +242,16 @@ void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, si
|
|||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
bufL[h]=os[0];
|
||||
bufR[h]=os[1];
|
||||
buf[0][h]=os[0];
|
||||
buf[1][h]=os[1];
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformGenesis::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformGenesis::acquire(short** buf, size_t len) {
|
||||
if (useYMFM) {
|
||||
acquire_ymfm(bufL,bufR,start,len);
|
||||
acquire_ymfm(buf,len);
|
||||
} else {
|
||||
acquire_nuked(bufL,bufR,start,len);
|
||||
acquire_nuked(buf,len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1193,8 +1193,8 @@ void DivPlatformGenesis::reset() {
|
|||
delay=0;
|
||||
}
|
||||
|
||||
bool DivPlatformGenesis::isStereo() {
|
||||
return true;
|
||||
int DivPlatformGenesis::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformGenesis::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -92,13 +92,13 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
inline void processDAC(int iRate);
|
||||
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_nuked(short** buf, size_t len);
|
||||
void acquire_ymfm(short** buf, size_t len);
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
void fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
|
@ -110,7 +110,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void setYMFM(bool use);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
|
|
|
@ -54,8 +54,8 @@ inline void DivPlatformK007232::chWrite(unsigned char ch, unsigned int addr, uns
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformK007232::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformK007232::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if ((--delay)<=0) {
|
||||
delay=MAX(0,delay);
|
||||
if (!writes.empty()) {
|
||||
|
@ -76,15 +76,15 @@ void DivPlatformK007232::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
const unsigned char vol1=regPool[0x10],vol2=regPool[0x11];
|
||||
const signed int lout[2]={(k007232.output(0)*(vol1&0xf)),(k007232.output(1)*(vol2&0xf))};
|
||||
const signed int rout[2]={(k007232.output(0)*((vol1>>4)&0xf)),(k007232.output(1)*((vol2>>4)&0xf))};
|
||||
bufL[h]=(lout[0]+lout[1])<<4;
|
||||
bufR[h]=(rout[0]+rout[1])<<4;
|
||||
buf[0][h]=(lout[0]+lout[1])<<4;
|
||||
buf[1][h]=(rout[0]+rout[1])<<4;
|
||||
for (int i=0; i<2; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<4;
|
||||
}
|
||||
} else {
|
||||
const unsigned char vol=regPool[0xc];
|
||||
const signed int out[2]={(k007232.output(0)*(vol&0xf)),(k007232.output(1)*((vol>>4)&0xf))};
|
||||
bufL[h]=bufR[h]=(out[0]+out[1])<<4;
|
||||
buf[0][h]=(out[0]+out[1])<<4;
|
||||
for (int i=0; i<2; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<5;
|
||||
}
|
||||
|
@ -448,8 +448,8 @@ void DivPlatformK007232::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformK007232::isStereo() {
|
||||
return stereo;
|
||||
int DivPlatformK007232::getOutputCount() {
|
||||
return stereo?2:1;
|
||||
}
|
||||
|
||||
void DivPlatformK007232::notifyInsChange(int ins) {
|
||||
|
|
|
@ -80,7 +80,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
|
|||
void chWrite(unsigned char ch, unsigned int addr, unsigned char val);
|
||||
public:
|
||||
u8 read_sample(u8 ne, u32 address);
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -91,7 +91,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void notifyInsChange(int ins);
|
||||
void notifyWaveChange(int wave);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -130,8 +130,8 @@ const char** DivPlatformLynx::getRegisterSheet() {
|
|||
return regCheatSheetLynx;
|
||||
}
|
||||
|
||||
void DivPlatformLynx::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformLynx::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
for (int i=0; i<4; i++) {
|
||||
if (chan[i].pcm && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||
chan[i].sampleAccum-=chan[i].sampleFreq;
|
||||
|
@ -156,7 +156,7 @@ void DivPlatformLynx::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
}
|
||||
}
|
||||
|
||||
mikey->sampleAudio( bufL + h, bufR + h, 1, oscBuf );
|
||||
mikey->sampleAudio(buf[0]+h,buf[1]+h,1,oscBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,8 +393,8 @@ void DivPlatformLynx::muteChannel(int ch, bool mute) {
|
|||
if (chan[ch].active) WRITE_VOLUME(ch,(isMuted[ch]?0:(chan[ch].outVol&127)));
|
||||
}
|
||||
|
||||
bool DivPlatformLynx::isStereo() {
|
||||
return true;
|
||||
int DivPlatformLynx::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void DivPlatformLynx::forceIns() {
|
||||
|
@ -509,12 +509,12 @@ DivPlatformLynx::MikeyFreqDiv::MikeyFreqDiv(int frequency) {
|
|||
if (top>7)
|
||||
{
|
||||
clockDivider=top-7;
|
||||
backup=frequency>>(top-7);
|
||||
backup=clamped>>(top-7);
|
||||
}
|
||||
else
|
||||
{
|
||||
clockDivider=0;
|
||||
backup=frequency;
|
||||
backup=clamped;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class DivPlatformLynx: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -79,7 +79,7 @@ class DivPlatformLynx: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
//int getPortaFloor(int ch);
|
||||
|
|
|
@ -43,8 +43,8 @@ const char** DivPlatformMMC5::getRegisterSheet() {
|
|||
return regCheatSheetMMC5;
|
||||
}
|
||||
|
||||
void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformMMC5::acquire(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (dacSample!=-1) {
|
||||
dacPeriod+=dacRate;
|
||||
if (dacPeriod>=rate) {
|
||||
|
@ -81,7 +81,7 @@ void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
}
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
bufL[i]=sample;
|
||||
buf[0][i]=sample;
|
||||
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
|
|
|
@ -50,7 +50,7 @@ class DivPlatformMMC5: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -45,8 +45,8 @@ const char** DivPlatformMSM5232::getRegisterSheet() {
|
|||
return regCheatSheetMSM5232;
|
||||
}
|
||||
|
||||
void DivPlatformMSM5232::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformMSM5232::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
msm->write(w.addr,w.val);
|
||||
|
@ -75,9 +75,9 @@ void DivPlatformMSM5232::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
}
|
||||
|
||||
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
||||
bufL[h]=0;
|
||||
buf[0][h]=0;
|
||||
for (int i=0; i<8; i++) {
|
||||
bufL[h]+=(temp[i]*partVolume[i])>>8;
|
||||
buf[0][h]+=(temp[i]*partVolume[i])>>8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,8 +371,8 @@ void DivPlatformMSM5232::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformMSM5232::isStereo() {
|
||||
return false;
|
||||
int DivPlatformMSM5232::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool DivPlatformMSM5232::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -60,7 +60,7 @@ class DivPlatformMSM5232: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -71,7 +71,7 @@ class DivPlatformMSM5232: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -30,12 +30,12 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformMSM6258::acquire(short** buf, size_t len) {
|
||||
short* outs[2]={
|
||||
&msmOut,
|
||||
NULL
|
||||
};
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (--msmClockCount<0) {
|
||||
if (--msmDividerCount<=0) {
|
||||
if (!writes.empty()) {
|
||||
|
@ -78,12 +78,12 @@ void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
}
|
||||
|
||||
if (isMuted[0]) {
|
||||
bufL[h]=0;
|
||||
bufR[h]=0;
|
||||
buf[0][h]=0;
|
||||
buf[1][h]=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=0;
|
||||
} else {
|
||||
bufL[h]=(msmPan&2)?msmOut:0;
|
||||
bufR[h]=(msmPan&1)?msmOut:0;
|
||||
buf[0][h]=(msmPan&2)?msmOut:0;
|
||||
buf[1][h]=(msmPan&1)?msmOut:0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=msmPan?msmOut:0;
|
||||
}
|
||||
}
|
||||
|
@ -336,8 +336,8 @@ void DivPlatformMSM6258::reset() {
|
|||
delay=0;
|
||||
}
|
||||
|
||||
bool DivPlatformMSM6258::isStereo() {
|
||||
return true;
|
||||
int DivPlatformMSM6258::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformMSM6258::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -58,7 +58,7 @@ class DivPlatformMSM6258: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -69,7 +69,7 @@ class DivPlatformMSM6258: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void notifyInsChange(int ins);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -37,8 +37,8 @@ u8 DivPlatformMSM6295::read_byte(u32 address) {
|
|||
return adpcmMem[address&0x3ffff];
|
||||
}
|
||||
|
||||
void DivPlatformMSM6295::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformMSM6295::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (delay<=0) {
|
||||
if (!writes.empty()) {
|
||||
QueuedWrite& w=writes.front();
|
||||
|
@ -75,7 +75,7 @@ void DivPlatformMSM6295::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
msm.tick();
|
||||
msm.tick();
|
||||
|
||||
bufL[h]=msm.out()<<4;
|
||||
buf[0][h]=msm.out()<<4;
|
||||
|
||||
if (++updateOsc>=22) {
|
||||
updateOsc=0;
|
||||
|
|
|
@ -64,7 +64,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
|
|||
|
||||
public:
|
||||
virtual u8 read_byte(u32 address) override;
|
||||
virtual void acquire(short* bufL, short* bufR, size_t start, size_t len) override;
|
||||
virtual void acquire(short** buf, size_t len) override;
|
||||
virtual int dispatch(DivCommand c) override;
|
||||
virtual void* getChanState(int chan) override;
|
||||
virtual DivMacroInt* getChanMacroInt(int ch) override;
|
||||
|
|
|
@ -108,13 +108,13 @@ const char** DivPlatformN163::getRegisterSheet() {
|
|||
return regCheatSheetN163;
|
||||
}
|
||||
|
||||
void DivPlatformN163::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformN163::acquire(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
n163.tick();
|
||||
int out=(n163.out()<<6)*2; // scale to 16 bit
|
||||
if (out>32767) out=32767;
|
||||
if (out<-32768) out=-32768;
|
||||
bufL[i]=bufR[i]=out;
|
||||
buf[0][i]=out;
|
||||
|
||||
if (n163.voice_cycle()==0x78) for (int i=0; i<8; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=n163.voice_out(i)<<7;
|
||||
|
|
|
@ -74,7 +74,7 @@ class DivPlatformN163: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -151,7 +151,7 @@ const char** DivPlatformNamcoWSG::getRegisterSheet() {
|
|||
return regCheatSheetNamcoWSG;
|
||||
}
|
||||
|
||||
void DivPlatformNamcoWSG::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformNamcoWSG::acquire(short** buf, size_t len) {
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
switch (devType) {
|
||||
|
@ -171,11 +171,11 @@ void DivPlatformNamcoWSG::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
regPool[w.addr&0x3f]=w.val;
|
||||
writes.pop();
|
||||
}
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
short* buf[2]={
|
||||
bufL+h, bufR+h
|
||||
for (size_t h=0; h<len; h++) {
|
||||
short* bufC[2]={
|
||||
buf[0]+h, buf[1]+h
|
||||
};
|
||||
namco->sound_stream_update(buf,1);
|
||||
namco->sound_stream_update(bufC,1);
|
||||
for (int i=0; i<chans; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=namco->m_channel_list[i].last_out*chans;
|
||||
}
|
||||
|
@ -494,8 +494,8 @@ void DivPlatformNamcoWSG::reset() {
|
|||
namco->device_start(NULL);
|
||||
}
|
||||
|
||||
bool DivPlatformNamcoWSG::isStereo() {
|
||||
return (devType==30);
|
||||
int DivPlatformNamcoWSG::getOutputCount() {
|
||||
return (devType==30)?2:1;
|
||||
}
|
||||
|
||||
bool DivPlatformNamcoWSG::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -54,7 +54,7 @@ class DivPlatformNamcoWSG: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -65,7 +65,7 @@ class DivPlatformNamcoWSG: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void setDeviceType(int type);
|
||||
void setFlags(const DivConfig& flags);
|
||||
|
|
|
@ -100,8 +100,8 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
|
|||
} \
|
||||
}
|
||||
|
||||
void DivPlatformNES::acquire_puNES(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformNES::acquire_puNES(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
doPCM;
|
||||
|
||||
apu_tick(nes,NULL);
|
||||
|
@ -112,7 +112,7 @@ void DivPlatformNES::acquire_puNES(short* bufL, short* bufR, size_t start, size_
|
|||
int sample=(pulse_output(nes)+tnd_output(nes))<<6;
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
bufL[i]=sample;
|
||||
buf[0][i]=sample;
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=isMuted[0]?0:(nes->S1.output<<11);
|
||||
|
@ -124,10 +124,10 @@ void DivPlatformNES::acquire_puNES(short* bufL, short* bufR, size_t start, size_
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformNES::acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformNES::acquire_NSFPlay(short** buf, size_t len) {
|
||||
int out1[2];
|
||||
int out2[2];
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
doPCM;
|
||||
|
||||
nes1_NP->Tick(1);
|
||||
|
@ -139,7 +139,7 @@ void DivPlatformNES::acquire_NSFPlay(short* bufL, short* bufR, size_t start, siz
|
|||
int sample=(out1[0]+out1[1]+out2[0]+out2[1])<<1;
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
bufL[i]=sample;
|
||||
buf[0][i]=sample;
|
||||
if (++writeOscBuf>=32) {
|
||||
writeOscBuf=0;
|
||||
oscBuf[0]->data[oscBuf[0]->needle++]=nes1_NP->out[0]<<11;
|
||||
|
@ -151,11 +151,11 @@ void DivPlatformNES::acquire_NSFPlay(short* bufL, short* bufR, size_t start, siz
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformNES::acquire(short** buf, size_t len) {
|
||||
if (useNP) {
|
||||
acquire_NSFPlay(bufL,bufR,start,len);
|
||||
acquire_NSFPlay(buf,len);
|
||||
} else {
|
||||
acquire_puNES(bufL,bufR,start,len);
|
||||
acquire_puNES(buf,len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +278,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
ntPos+=chan[i].arpOff;
|
||||
}
|
||||
}
|
||||
ntPos+=chan[i].pitch2;
|
||||
if (parent->song.properNoiseLayout) {
|
||||
chan[i].freq=15-(ntPos&15);
|
||||
} else {
|
||||
|
|
|
@ -68,11 +68,11 @@ class DivPlatformNES: public DivDispatch {
|
|||
|
||||
void doWrite(unsigned short addr, unsigned char data);
|
||||
unsigned char calcDPCMRate(int inRate);
|
||||
void acquire_puNES(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_NSFPlay(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_puNES(short** buf, size_t len);
|
||||
void acquire_NSFPlay(short** buf, size_t len);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -159,13 +159,13 @@ const int orderedOpsL[4]={
|
|||
#define ADDR_FREQH 0xb0
|
||||
#define ADDR_LR_FB_ALG 0xc0
|
||||
|
||||
void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
static short o[2];
|
||||
static int os[2];
|
||||
void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
|
||||
static short o[4];
|
||||
static int os[4];
|
||||
static ymfm::ymfm_output<2> aOut;
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
os[0]=0; os[1]=0;
|
||||
for (size_t h=0; h<len; h++) {
|
||||
os[0]=0; os[1]=0; os[2]=0; os[3]=0;
|
||||
if (!writes.empty() && --delay<0) {
|
||||
delay=1;
|
||||
QueuedWrite& w=writes.front();
|
||||
|
@ -194,11 +194,14 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
}
|
||||
|
||||
if (downsample) {
|
||||
OPL3_GenerateResampled(&fm,o);
|
||||
OPL3_Generate4ChResampled(&fm,o);
|
||||
} else {
|
||||
OPL3_Generate(&fm,o);
|
||||
OPL3_Generate4Ch(&fm,o);
|
||||
}
|
||||
os[0]+=o[0]; os[1]+=o[1];
|
||||
os[0]+=o[0];
|
||||
os[1]+=o[1];
|
||||
os[2]+=o[2];
|
||||
os[3]+=o[3];
|
||||
|
||||
if (adpcmChan>=0) {
|
||||
adpcmB->clock();
|
||||
|
@ -225,6 +228,12 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
if (fm.channel[i].out[1]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
|
||||
}
|
||||
if (fm.channel[i].out[2]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
|
||||
}
|
||||
if (fm.channel[i].out[3]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
|
||||
}
|
||||
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
|
||||
oscBuf[i]->needle++;
|
||||
}
|
||||
|
@ -244,6 +253,12 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
if (fm.channel[i].out[1]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
|
||||
}
|
||||
if (fm.channel[i].out[2]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
|
||||
}
|
||||
if (fm.channel[i].out[3]!=NULL) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
|
||||
}
|
||||
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
|
||||
oscBuf[i]->needle++;
|
||||
}
|
||||
|
@ -255,18 +270,35 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
bufL[h]=os[0];
|
||||
if (oplType==3 || oplType==759) {
|
||||
bufR[h]=os[1];
|
||||
if (os[2]<-32768) os[2]=-32768;
|
||||
if (os[2]>32767) os[2]=32767;
|
||||
|
||||
if (os[3]<-32768) os[3]=-32768;
|
||||
if (os[3]>32767) os[3]=32767;
|
||||
|
||||
buf[0][h]=os[0];
|
||||
if (totalOutputs>1) {
|
||||
buf[1][h]=os[1];
|
||||
}
|
||||
if (totalOutputs>2) {
|
||||
buf[2][h]=os[2];
|
||||
}
|
||||
if (totalOutputs>3) {
|
||||
buf[3][h]=os[3];
|
||||
}
|
||||
if (totalOutputs==6) {
|
||||
// placeholder for OPL4
|
||||
buf[4][h]=0;
|
||||
buf[5][h]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformOPL::acquire(short** buf, size_t len) {
|
||||
//if (useYMFM) {
|
||||
// acquire_ymfm(bufL,bufR,start,len);
|
||||
// acquire_ymfm(buf,len);
|
||||
//} else {
|
||||
acquire_nuked(bufL,bufR,start,len);
|
||||
acquire_nuked(buf,len);
|
||||
//}
|
||||
}
|
||||
|
||||
|
@ -314,13 +346,13 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
}
|
||||
|
||||
if (oplType==3 && chan[i].std.panL.had) {
|
||||
chan[i].pan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1);
|
||||
chan[i].pan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1)|((chan[i].std.panL.val&4)<<1)|((chan[i].std.panL.val&8)>>1);
|
||||
}
|
||||
|
||||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||
CLAMP_VAR(chan[i].pitch2,-131071,131071);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
|
@ -347,9 +379,9 @@ void DivPlatformOPL::tick(bool sysTick) {
|
|||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
|
||||
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
|
||||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -659,9 +691,9 @@ void DivPlatformOPL::muteChannel(int ch, bool mute) {
|
|||
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
|
||||
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
|
||||
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -797,7 +829,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1));
|
||||
} else {
|
||||
oldWrites[chanMap[ch]+ADDR_LR_FB_ALG]=-1;
|
||||
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
|
||||
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -847,10 +879,10 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
}
|
||||
} else {
|
||||
oldWrites[chanMap[c.chan]+ADDR_LR_FB_ALG]=-1;
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
oldWrites[chanMap[c.chan+1]+ADDR_LR_FB_ALG]=-1;
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -956,10 +988,11 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
case DIV_CMD_PANNING: {
|
||||
if (oplType!=3) break;
|
||||
if (c.chan==adpcmChan) break;
|
||||
if (c.value==0 && c.value2==0) {
|
||||
chan[c.chan].pan=3;
|
||||
chan[c.chan].pan&=~3;
|
||||
if (c.value==0 && c.value2==0 && compatPan) {
|
||||
chan[c.chan].pan|=3;
|
||||
} else {
|
||||
chan[c.chan].pan=(c.value>0)|((c.value2>0)<<1);
|
||||
chan[c.chan].pan|=(c.value>0)|((c.value2>0)<<1);
|
||||
}
|
||||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||
if (isMuted[c.chan]) {
|
||||
|
@ -968,9 +1001,36 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIV_CMD_SURROUND_PANNING: {
|
||||
if (oplType!=3) break;
|
||||
if (c.chan==adpcmChan) break;
|
||||
|
||||
if (c.value==2) {
|
||||
chan[c.chan].pan&=3;
|
||||
if (c.value2>0) chan[c.chan].pan|=4;
|
||||
} else if (c.value==3) {
|
||||
if (c.value2>0) chan[c.chan].pan|=8;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1049,9 +1109,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
|
||||
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1431,9 +1491,9 @@ void DivPlatformOPL::forceIns() {
|
|||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1));
|
||||
}
|
||||
} else {
|
||||
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
|
||||
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
|
||||
if (ops==4) {
|
||||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
|
||||
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -1568,8 +1628,8 @@ void DivPlatformOPL::reset() {
|
|||
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
|
||||
}
|
||||
|
||||
bool DivPlatformOPL::isStereo() {
|
||||
return (oplType==3 || oplType==759);
|
||||
int DivPlatformOPL::getOutputCount() {
|
||||
return totalOutputs;
|
||||
}
|
||||
|
||||
bool DivPlatformOPL::keyOffAffectsArp(int ch) {
|
||||
|
@ -1625,6 +1685,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
|||
if (type==8950) {
|
||||
adpcmChan=drums?11:9;
|
||||
}
|
||||
totalOutputs=1;
|
||||
break;
|
||||
case 3: case 4: case 759:
|
||||
slotsNonDrums=slotsOPL3;
|
||||
|
@ -1643,6 +1704,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
|
|||
chipFreqBase=32768*684;
|
||||
downsample=true;
|
||||
}
|
||||
totalOutputs=(type==4)?6:4;
|
||||
break;
|
||||
}
|
||||
chipType=type;
|
||||
|
@ -1681,6 +1743,8 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
|
|||
rate=chipClock/36;
|
||||
}*/
|
||||
|
||||
compatPan=false;
|
||||
|
||||
switch (chipType) {
|
||||
default:
|
||||
case 1: case 2: case 8950:
|
||||
|
@ -1736,12 +1800,14 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
|
|||
rate=chipClock/768;
|
||||
chipRateBase=chipClock/684;
|
||||
downsample=true;
|
||||
totalOutputs=2; // Stereo output only
|
||||
break;
|
||||
default: // YMF262
|
||||
chipFreqBase=32768*288;
|
||||
rate=chipClock/288;
|
||||
chipRateBase=rate;
|
||||
downsample=false;
|
||||
totalOutputs=4;
|
||||
break;
|
||||
}
|
||||
reset();
|
||||
|
@ -1768,6 +1834,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
|
|||
chipClock=rate*288;
|
||||
break;
|
||||
}
|
||||
compatPan=flags.getBool("compatPan",false);
|
||||
|
||||
for (int i=0; i<20; i++) {
|
||||
oscBuf[i]->rate=rate;
|
||||
|
|
|
@ -81,7 +81,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
const unsigned short* chanMap;
|
||||
const unsigned char* outChanMap;
|
||||
int chipFreqBase, chipRateBase;
|
||||
int delay, chipType, oplType, chans, melodicChans, totalChans, adpcmChan, sampleBank;
|
||||
int delay, chipType, oplType, chans, melodicChans, totalChans, adpcmChan, sampleBank, totalOutputs;
|
||||
unsigned char lastBusy;
|
||||
unsigned char drumState;
|
||||
unsigned char drumVol[5];
|
||||
|
@ -92,7 +92,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
|
||||
unsigned char lfoValue;
|
||||
|
||||
bool useYMFM, update4OpMask, pretendYMU, downsample;
|
||||
bool useYMFM, update4OpMask, pretendYMU, downsample, compatPan;
|
||||
|
||||
short oldWrites[512];
|
||||
short pendingWrites[512];
|
||||
|
@ -104,11 +104,11 @@ class DivPlatformOPL: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||
//void acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_nuked(short** buf, size_t len);
|
||||
//void acquire_ymfm(short** buf, size_t len);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -119,7 +119,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void setYMFM(bool use);
|
||||
void setOPLType(int type, bool drums);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
|
|
|
@ -39,11 +39,11 @@ const unsigned char visMapOPLL[9]={
|
|||
6, 7, 8, 3, 4, 5, 0, 1, 2
|
||||
};
|
||||
|
||||
void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformOPLL::acquire_nuked(short** buf, size_t len) {
|
||||
static int o[2];
|
||||
static int os;
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
os=0;
|
||||
for (int i=0; i<9; i++) {
|
||||
if (!writes.empty() && --delay<0) {
|
||||
|
@ -83,15 +83,15 @@ void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size
|
|||
os*=50;
|
||||
if (os<-32768) os=-32768;
|
||||
if (os>32767) os=32767;
|
||||
bufL[h]=os;
|
||||
buf[0][h]=os;
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformOPLL::acquire_ymfm(short** buf, size_t len) {
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
acquire_nuked(bufL,bufR,start,len);
|
||||
void DivPlatformOPLL::acquire(short** buf, size_t len) {
|
||||
acquire_nuked(buf,len);
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::tick(bool sysTick) {
|
||||
|
@ -124,7 +124,7 @@ void DivPlatformOPLL::tick(bool sysTick) {
|
|||
if (chan[i].std.pitch.had) {
|
||||
if (chan[i].std.pitch.mode) {
|
||||
chan[i].pitch2+=chan[i].std.pitch.val;
|
||||
CLAMP_VAR(chan[i].pitch2,-32768,32767);
|
||||
CLAMP_VAR(chan[i].pitch2,-65535,65535);
|
||||
} else {
|
||||
chan[i].pitch2=chan[i].std.pitch.val;
|
||||
}
|
||||
|
|
|
@ -77,11 +77,11 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_nuked(short** buf, size_t len);
|
||||
void acquire_ymfm(short** buf, size_t len);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -53,8 +53,8 @@ const char** DivPlatformPCE::getRegisterSheet() {
|
|||
return regCheatSheetPCE;
|
||||
}
|
||||
|
||||
void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformPCE::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
// PCM part
|
||||
for (int i=0; i<6; i++) {
|
||||
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||
|
@ -113,8 +113,8 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
if (tempR[0]>32767) tempR[0]=32767;
|
||||
|
||||
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
||||
bufL[h]=tempL[0];
|
||||
bufR[h]=tempR[0];
|
||||
buf[0][h]=tempL[0];
|
||||
buf[1][h]=tempR[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,7 @@ void DivPlatformPCE::tick(bool sysTick) {
|
|||
chan[i].dacRate=((double)chipClock/2)/MAX(1,off*chan[i].freq);
|
||||
if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dacRate);
|
||||
}
|
||||
if (chan[i].freq<1) chan[i].freq=1;
|
||||
if (chan[i].freq>4095) chan[i].freq=4095;
|
||||
chWrite(i,0x02,chan[i].freq&0xff);
|
||||
chWrite(i,0x03,chan[i].freq>>8);
|
||||
|
@ -547,8 +548,8 @@ void DivPlatformPCE::reset() {
|
|||
delay=500;
|
||||
}
|
||||
|
||||
bool DivPlatformPCE::isStereo() {
|
||||
return true;
|
||||
int DivPlatformPCE::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformPCE::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -76,7 +76,7 @@ class DivPlatformPCE: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -87,7 +87,7 @@ class DivPlatformPCE: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyWaveChange(int wave);
|
||||
|
|
|
@ -26,13 +26,13 @@
|
|||
// to ease the driver, freqency register is a 8.16 counter relative to output sample rate
|
||||
#define CHIP_FREQBASE 65536
|
||||
|
||||
void DivPlatformPCMDAC::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
|
||||
const int depthScale=(15-outDepth);
|
||||
int output=0;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (!chan[0].active || isMuted) {
|
||||
bufL[h]=0;
|
||||
bufR[h]=0;
|
||||
buf[0][h]=0;
|
||||
buf[1][h]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
continue;
|
||||
}
|
||||
|
@ -157,12 +157,12 @@ void DivPlatformPCMDAC::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
output=output*chan[0].vol*chan[0].envVol/16384;
|
||||
oscBuf->data[oscBuf->needle++]=output;
|
||||
if (outStereo) {
|
||||
bufL[h]=((output*chan[0].panL)>>(depthScale+8))<<depthScale;
|
||||
bufR[h]=((output*chan[0].panR)>>(depthScale+8))<<depthScale;
|
||||
buf[0][h]=((output*chan[0].panL)>>(depthScale+8))<<depthScale;
|
||||
buf[1][h]=((output*chan[0].panR)>>(depthScale+8))<<depthScale;
|
||||
} else {
|
||||
output=(output>>depthScale)<<depthScale;
|
||||
bufL[h]=output;
|
||||
bufR[h]=output;
|
||||
buf[0][h]=output;
|
||||
buf[1][h]=output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -410,8 +410,8 @@ void DivPlatformPCMDAC::reset() {
|
|||
chan[0].ws.init(NULL,32,255);
|
||||
}
|
||||
|
||||
bool DivPlatformPCMDAC::isStereo() {
|
||||
return true;
|
||||
int DivPlatformPCMDAC::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
DivMacroInt* DivPlatformPCMDAC::getChanMacroInt(int ch) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class DivPlatformPCMDAC: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
|
@ -75,7 +75,7 @@ class DivPlatformPCMDAC: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsChange(int ins);
|
||||
|
|
|
@ -193,9 +193,9 @@ const char** DivPlatformPCSpeaker::getRegisterSheet() {
|
|||
const float cut=0.05;
|
||||
const float reso=0.06;
|
||||
|
||||
void DivPlatformPCSpeaker::acquire_unfilt(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPCSpeaker::acquire_unfilt(short** buf, size_t len) {
|
||||
int out=0;
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (on) {
|
||||
pos-=PCSPKR_DIVIDER;
|
||||
if (pos>freq) pos=freq;
|
||||
|
@ -207,17 +207,17 @@ void DivPlatformPCSpeaker::acquire_unfilt(short* bufL, short* bufR, size_t start
|
|||
}
|
||||
}
|
||||
out=(pos>(freq>>1) && !isMuted[0])?32767:0;
|
||||
bufL[i]=out;
|
||||
buf[0][i]=out;
|
||||
oscBuf->data[oscBuf->needle++]=out;
|
||||
} else {
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformPCSpeaker::acquire_cone(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformPCSpeaker::acquire_cone(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (on) {
|
||||
pos-=PCSPKR_DIVIDER;
|
||||
if (pos>freq) pos=freq;
|
||||
|
@ -234,17 +234,17 @@ void DivPlatformPCSpeaker::acquire_cone(short* bufL, short* bufR, size_t start,
|
|||
float out=(low+band)*0.75;
|
||||
if (out>1.0) out=1.0;
|
||||
if (out<-1.0) out=-1.0;
|
||||
bufL[i]=out*32767;
|
||||
buf[0][i]=out*32767;
|
||||
oscBuf->data[oscBuf->needle++]=out*32767;
|
||||
} else {
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformPCSpeaker::acquire_piezo(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
void DivPlatformPCSpeaker::acquire_piezo(short** buf, size_t len) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (on) {
|
||||
pos-=PCSPKR_DIVIDER;
|
||||
if (pos>freq) pos=freq;
|
||||
|
@ -261,10 +261,10 @@ void DivPlatformPCSpeaker::acquire_piezo(short* bufL, short* bufR, size_t start,
|
|||
float out=band*0.15-(next-low)*0.06;
|
||||
if (out>1.0) out=1.0;
|
||||
if (out<-1.0) out=-1.0;
|
||||
bufL[i]=out*32767;
|
||||
buf[0][i]=out*32767;
|
||||
oscBuf->data[oscBuf->needle++]=out*32767;
|
||||
} else {
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
|||
realQueueLock.lock();
|
||||
#ifdef __linux__
|
||||
struct timespec ts;
|
||||
double addition=1000000000.0*(double)delay/(double)rate;
|
||||
double addition=1000000000.0*(double)delay/parent->getAudioDescGot().rate;
|
||||
addition+=1500000000.0*((double)parent->getAudioDescGot().bufsize/parent->getAudioDescGot().rate);
|
||||
if (clock_gettime(CLOCK_MONOTONIC,&ts)<0) {
|
||||
ts.tv_sec=0;
|
||||
|
@ -294,14 +294,14 @@ void DivPlatformPCSpeaker::beepFreq(int freq, int delay) {
|
|||
realOutCond.notify_one();
|
||||
}
|
||||
|
||||
void DivPlatformPCSpeaker::acquire_real(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPCSpeaker::acquire_real(short** buf, size_t len) {
|
||||
int out=0;
|
||||
if (lastOn!=on || lastFreq!=freq) {
|
||||
lastOn=on;
|
||||
lastFreq=freq;
|
||||
beepFreq((on && !isMuted[0])?freq:0,start);
|
||||
beepFreq((on && !isMuted[0])?freq:0,parent->getBufferPos());
|
||||
}
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (on) {
|
||||
pos-=PCSPKR_DIVIDER;
|
||||
if (pos>freq) pos=freq;
|
||||
|
@ -317,23 +317,23 @@ void DivPlatformPCSpeaker::acquire_real(short* bufL, short* bufR, size_t start,
|
|||
} else {
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformPCSpeaker::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPCSpeaker::acquire(short** buf, size_t len) {
|
||||
switch (speakerType) {
|
||||
case 0:
|
||||
acquire_unfilt(bufL,bufR,start,len);
|
||||
acquire_unfilt(buf,len);
|
||||
break;
|
||||
case 1:
|
||||
acquire_cone(bufL,bufR,start,len);
|
||||
acquire_cone(buf,len);
|
||||
break;
|
||||
case 2:
|
||||
acquire_piezo(bufL,bufR,start,len);
|
||||
acquire_piezo(buf,len);
|
||||
break;
|
||||
case 3:
|
||||
acquire_real(bufL,bufR,start,len);
|
||||
acquire_real(buf,len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,14 +61,14 @@ class DivPlatformPCSpeaker: public DivDispatch {
|
|||
|
||||
void beepFreq(int freq, int delay=0);
|
||||
|
||||
void acquire_unfilt(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_cone(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_piezo(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_real(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_unfilt(short** buf, size_t len);
|
||||
void acquire_cone(short** buf, size_t len);
|
||||
void acquire_piezo(short** buf, size_t len);
|
||||
void acquire_real(short** buf, size_t len);
|
||||
|
||||
public:
|
||||
void pcSpeakerThread();
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -55,14 +55,14 @@ void DivPlatformPET::rWrite(unsigned int addr, unsigned char val) {
|
|||
regPool[addr]=val;
|
||||
}
|
||||
|
||||
void DivPlatformPET::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPET::acquire(short** buf, size_t len) {
|
||||
bool hwSROutput=((regPool[11]>>2)&7)==4;
|
||||
if (chan[0].enable) {
|
||||
int reload=regPool[8]*2+4;
|
||||
if (!hwSROutput) {
|
||||
reload+=regPool[9]*512;
|
||||
}
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (SAMP_DIVIDER>chan[0].cnt) {
|
||||
chan[0].out=(chan[0].sreg&1)*32767;
|
||||
chan[0].sreg=(chan[0].sreg>>1)|((chan[0].sreg&1)<<7);
|
||||
|
@ -70,17 +70,15 @@ void DivPlatformPET::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
} else {
|
||||
chan[0].cnt-=SAMP_DIVIDER;
|
||||
}
|
||||
bufL[h]=chan[0].out;
|
||||
bufR[h]=chan[0].out;
|
||||
buf[0][h]=chan[0].out;
|
||||
oscBuf->data[oscBuf->needle++]=chan[0].out;
|
||||
}
|
||||
// emulate driver writes to PCR
|
||||
if (!hwSROutput) regPool[12]=chan[0].out?0xe0:0xc0;
|
||||
} else {
|
||||
chan[0].out=0;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
bufL[h]=0;
|
||||
bufR[h]=0;
|
||||
for (size_t h=0; h<len; h++) {
|
||||
buf[0][h]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
}
|
||||
|
@ -287,8 +285,8 @@ void DivPlatformPET::reset() {
|
|||
chan[0].std.setEngine(parent);
|
||||
}
|
||||
|
||||
bool DivPlatformPET::isStereo() {
|
||||
return false;
|
||||
int DivPlatformPET::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DivPlatformPET::notifyInsDeletion(void* ins) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class DivPlatformPET: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -57,7 +57,7 @@ class DivPlatformPET: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
void notifyInsDeletion(void* ins);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
const char** getRegisterSheet();
|
||||
|
|
|
@ -86,9 +86,9 @@ void DivPlatformPokeMini::rWrite(unsigned char addr, unsigned char val) {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformPokeMini::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPokeMini::acquire(short** buf, size_t len) {
|
||||
int out=0;
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
for (int j=0; j<PCSPKR_DIVIDER; j++) {
|
||||
elapsedMain++;
|
||||
if (on) {
|
||||
|
@ -102,10 +102,10 @@ void DivPlatformPokeMini::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
}
|
||||
if (on) {
|
||||
out=(pos>=pivot && !isMuted[0])?volTable[vol&3]:0;
|
||||
bufL[i]=out;
|
||||
buf[0][i]=out;
|
||||
oscBuf->data[oscBuf->needle++]=out;
|
||||
} else {
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class DivPlatformPokeMini: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -64,16 +64,16 @@ const char** DivPlatformPOKEY::getRegisterSheet() {
|
|||
return regCheatSheetPOKEY;
|
||||
}
|
||||
|
||||
void DivPlatformPOKEY::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPOKEY::acquire(short** buf, size_t len) {
|
||||
if (useAltASAP) {
|
||||
acquireASAP(bufL, start, len);
|
||||
acquireASAP(buf[0],len);
|
||||
} else {
|
||||
acquireMZ(bufL, start, len);
|
||||
acquireMZ(buf[0],len);
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformPOKEY::acquireMZ(short* buf, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformPOKEY::acquireMZ(short* buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
Update_pokey_sound_mz(&pokey,w.addr,w.val,0);
|
||||
|
@ -93,14 +93,14 @@ void DivPlatformPOKEY::acquireMZ(short* buf, size_t start, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformPOKEY::acquireASAP(short* buf, size_t start, size_t len) {
|
||||
void DivPlatformPOKEY::acquireASAP(short* buf, size_t len) {
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
altASAP.write(w.addr, w.val);
|
||||
writes.pop();
|
||||
}
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (++oscBufDelay>=2) {
|
||||
oscBufDelay=0;
|
||||
buf[h]=altASAP.sampleAudio(oscBuf);
|
||||
|
@ -241,7 +241,7 @@ void DivPlatformPOKEY::tick(bool sysTick) {
|
|||
chan[i].ctlChanged=false;
|
||||
if ((i==1 && audctl&16) || (i==3 && audctl&8)) {
|
||||
// ignore - channel is paired
|
||||
} else if ((i==0 && audctl&16) || (i==0 && audctl&8)) {
|
||||
} else if ((i==0 && audctl&16) || (i==2 && audctl&8)) {
|
||||
rWrite(1+(i<<1),0);
|
||||
rWrite(3+(i<<1),val);
|
||||
} else {
|
||||
|
|
|
@ -58,9 +58,9 @@ class DivPlatformPOKEY: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquireMZ(short* buf, size_t start, size_t len);
|
||||
void acquireASAP(short* buf, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
void acquireMZ(short* buf, size_t len);
|
||||
void acquireASAP(short* buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -23,19 +23,19 @@
|
|||
|
||||
#define CHIP_DIVIDER 1024
|
||||
|
||||
void DivPlatformPong::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformPong::acquire(short** buf, size_t len) {
|
||||
int out=0;
|
||||
for (size_t i=start; i<start+len; i++) {
|
||||
for (size_t i=0; i<len; i++) {
|
||||
if (on) {
|
||||
if (--pos<=0) {
|
||||
pos=(freq?2:1)<<4;
|
||||
flip=!flip;
|
||||
}
|
||||
out=(flip && !isMuted[0])?32767:0;
|
||||
bufL[i]=out;
|
||||
buf[0][i]=out;
|
||||
oscBuf->data[oscBuf->needle++]=out;
|
||||
} else {
|
||||
bufL[i]=0;
|
||||
buf[0][i]=0;
|
||||
oscBuf->data[oscBuf->needle++]=0;
|
||||
flip=false;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class DivPlatformPong: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
|
@ -265,11 +265,11 @@ const char** DivPlatformQSound::getRegisterSheet() {
|
|||
return regCheatSheetQSound;
|
||||
}
|
||||
|
||||
void DivPlatformQSound::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformQSound::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
qsound_update(&chip);
|
||||
bufL[h]=chip.out[0];
|
||||
bufR[h]=chip.out[1];
|
||||
buf[0][h]=chip.out[0];
|
||||
buf[1][h]=chip.out[1];
|
||||
|
||||
for (int i=0; i<19; i++) {
|
||||
int data=chip.voice_output[i]<<2;
|
||||
|
@ -636,8 +636,8 @@ void DivPlatformQSound::reset() {
|
|||
immWrite(Q1_ECHO_FEEDBACK, echoFeedback << 6);
|
||||
}
|
||||
|
||||
bool DivPlatformQSound::isStereo() {
|
||||
return true;
|
||||
int DivPlatformQSound::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool DivPlatformQSound::keyOffAffectsArp(int ch) {
|
||||
|
@ -707,11 +707,11 @@ const void* DivPlatformQSound::getSampleMem(int index) {
|
|||
}
|
||||
|
||||
size_t DivPlatformQSound::getSampleMemCapacity(int index) {
|
||||
return (index == 0 || index == 1) ? 16777216 : 0;
|
||||
return index == 0 ? 16777216 : index == 1 ? MAX(0,16777216 - sampleMemUsage) : 0;
|
||||
}
|
||||
|
||||
size_t DivPlatformQSound::getSampleMemUsage(int index) {
|
||||
return index == 0 ? sampleMemLen : index == 1 ? sampleMemLenBS : 0;
|
||||
return index == 0 ? sampleMemLen : index == 1 ? MAX(0,sampleMemLenBS - sampleMemUsage) : 0;
|
||||
}
|
||||
|
||||
bool DivPlatformQSound::isSampleLoaded(int index, int sample) {
|
||||
|
@ -766,6 +766,7 @@ void DivPlatformQSound::renderSamples(int sysID) {
|
|||
sampleMemLen=memPos+256;
|
||||
|
||||
memPos=(memPos+0xffff)&0xff0000;
|
||||
sampleMemUsage=memPos;
|
||||
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
|
@ -818,6 +819,7 @@ int DivPlatformQSound::init(DivEngine* p, int channels, int sugRate, const DivCo
|
|||
sampleMem=new unsigned char[getSampleMemCapacity()];
|
||||
sampleMemLen=0;
|
||||
sampleMemLenBS=0;
|
||||
sampleMemUsage=0;
|
||||
chip.rom_data=sampleMem;
|
||||
chip.rom_mask=0xffffff;
|
||||
reset();
|
||||
|
|
|
@ -50,6 +50,7 @@ class DivPlatformQSound: public DivDispatch {
|
|||
unsigned char* sampleMem;
|
||||
size_t sampleMemLen;
|
||||
size_t sampleMemLenBS;
|
||||
size_t sampleMemUsage;
|
||||
bool sampleLoaded[256];
|
||||
bool sampleLoadedBS[256];
|
||||
struct qsound_chip chip;
|
||||
|
@ -62,7 +63,7 @@ class DivPlatformQSound: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -74,7 +75,7 @@ class DivPlatformQSound: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsChange(int ins);
|
||||
|
|
|
@ -54,25 +54,27 @@ void DivPlatformRF5C68::chWrite(unsigned char ch, unsigned int addr, unsigned ch
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformRF5C68::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
short buf[16][256];
|
||||
// TODO: this code is weird
|
||||
// make sure newDispatch didn't break it up
|
||||
void DivPlatformRF5C68::acquire(short** buf, size_t len) {
|
||||
short bufC[16][256];
|
||||
short* chBufPtrs[16]={
|
||||
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],
|
||||
buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]
|
||||
bufC[0],bufC[1],bufC[2],bufC[3],bufC[4],bufC[5],bufC[6],bufC[7],
|
||||
bufC[8],bufC[9],bufC[10],bufC[11],bufC[12],bufC[13],bufC[14],bufC[15]
|
||||
};
|
||||
size_t pos=start;
|
||||
size_t pos=0;
|
||||
|
||||
for (int i=0; i<16; i++) {
|
||||
memset(buf[i],0,256*sizeof(short));
|
||||
memset(bufC[i],0,256*sizeof(short));
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
size_t blockLen=MIN(len,256);
|
||||
short* bufPtrs[2]={&bufL[pos],&bufR[pos]};
|
||||
short* bufPtrs[2]={&buf[0][pos],&buf[1][pos]};
|
||||
rf5c68.sound_stream_update(bufPtrs,chBufPtrs,blockLen);
|
||||
for (int i=0; i<8; i++) {
|
||||
for (size_t j=0; j<blockLen; j++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=buf[i*2][j]+buf[i*2+1][j];
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=bufC[i*2][j]+bufC[i*2+1][j];
|
||||
}
|
||||
}
|
||||
pos+=blockLen;
|
||||
|
@ -332,8 +334,8 @@ void DivPlatformRF5C68::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformRF5C68::isStereo() {
|
||||
return true;
|
||||
int DivPlatformRF5C68::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void DivPlatformRF5C68::notifyInsChange(int ins) {
|
||||
|
|
|
@ -56,7 +56,7 @@ class DivPlatformRF5C68: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -67,7 +67,7 @@ class DivPlatformRF5C68: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void setChipModel(int type);
|
||||
void notifyInsChange(int ins);
|
||||
void notifyWaveChange(int wave);
|
||||
|
|
|
@ -56,7 +56,7 @@ const char** DivPlatformSAA1099::getRegisterSheet() {
|
|||
return regCheatSheetSAA;
|
||||
}
|
||||
|
||||
void DivPlatformSAA1099::acquire_saaSound(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSAA1099::acquire_saaSound(short** buf, size_t len) {
|
||||
if (saaBufLen<len*2) {
|
||||
saaBufLen=len*2;
|
||||
for (int i=0; i<2; i++) {
|
||||
|
@ -73,19 +73,19 @@ void DivPlatformSAA1099::acquire_saaSound(short* bufL, short* bufR, size_t start
|
|||
saa_saaSound->GenerateMany((unsigned char*)saaBuf[0],len,oscBuf);
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=(short)((((unsigned short)saaBuf[0][1+(i<<1)])<<8)|(((unsigned short)saaBuf[0][1+(i<<1)])>>8));
|
||||
bufR[i+start]=(short)((((unsigned short)saaBuf[0][i<<1])<<8)|(((unsigned short)saaBuf[0][i<<1])>>8));
|
||||
buf[0][i]=(short)((((unsigned short)saaBuf[0][1+(i<<1)])<<8)|(((unsigned short)saaBuf[0][1+(i<<1)])>>8));
|
||||
buf[1][i]=(short)((((unsigned short)saaBuf[0][i<<1])<<8)|(((unsigned short)saaBuf[0][i<<1])>>8));
|
||||
}
|
||||
#else
|
||||
for (size_t i=0; i<len; i++) {
|
||||
bufL[i+start]=saaBuf[0][i<<1];
|
||||
bufR[i+start]=saaBuf[0][1+(i<<1)];
|
||||
buf[0][i]=saaBuf[0][i<<1];
|
||||
buf[1][i]=saaBuf[0][1+(i<<1)];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DivPlatformSAA1099::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
acquire_saaSound(bufL,bufR,start,len);
|
||||
void DivPlatformSAA1099::acquire(short** buf, size_t len) {
|
||||
acquire_saaSound(buf,len);
|
||||
}
|
||||
|
||||
inline unsigned char applyPan(unsigned char vol, unsigned char pan) {
|
||||
|
@ -419,8 +419,8 @@ void DivPlatformSAA1099::reset() {
|
|||
rWrite(0x1c,1);
|
||||
}
|
||||
|
||||
bool DivPlatformSAA1099::isStereo() {
|
||||
return true;
|
||||
int DivPlatformSAA1099::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int DivPlatformSAA1099::getPortaFloor(int ch) {
|
||||
|
|
|
@ -71,10 +71,10 @@ class DivPlatformSAA1099: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void acquire_saaSound(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_saaSound(short** buf, size_t len);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -86,7 +86,7 @@ class DivPlatformSAA1099: public DivDispatch {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
void setFlags(const DivConfig& flags);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
int getPortaFloor(int ch);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
void notifyInsDeletion(void* ins);
|
||||
|
|
|
@ -80,13 +80,13 @@ const char** DivPlatformSCC::getRegisterSheet() {
|
|||
return isPlus ? regCheatSheetSCCPlus : regCheatSheetSCC;
|
||||
}
|
||||
|
||||
void DivPlatformSCC::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
void DivPlatformSCC::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
for (int i=0; i<16; i++) {
|
||||
scc->tick();
|
||||
}
|
||||
short out=(short)scc->out()<<5;
|
||||
bufL[h]=bufR[h]=out;
|
||||
buf[0][h]=out;
|
||||
|
||||
for (int i=0; i<5; i++) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=scc->voice_out(i)<<7;
|
||||
|
@ -335,8 +335,8 @@ void DivPlatformSCC::reset() {
|
|||
lastUpdated34=0;
|
||||
}
|
||||
|
||||
bool DivPlatformSCC::isStereo() {
|
||||
return false;
|
||||
int DivPlatformSCC::getOutputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void DivPlatformSCC::notifyWaveChange(int wave) {
|
||||
|
|
|
@ -50,7 +50,7 @@ class DivPlatformSCC: public DivDispatch {
|
|||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -61,7 +61,7 @@ class DivPlatformSCC: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void notifyWaveChange(int wave);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
//#define rWrite(a,v) if (!skipRegisterWrites) {pendingWrites[a]=v;}
|
||||
//#define immWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} }
|
||||
|
||||
void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSegaPCM::acquire(short** buf, size_t len) {
|
||||
static int os[2];
|
||||
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
os[0]=0; os[1]=0;
|
||||
// do a PCM cycle
|
||||
pcmL=0; pcmR=0;
|
||||
|
@ -67,8 +67,8 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
if (os[1]<-32768) os[1]=-32768;
|
||||
if (os[1]>32767) os[1]=32767;
|
||||
|
||||
bufL[h]=os[0];
|
||||
bufR[h]=os[1];
|
||||
buf[0][h]=os[0];
|
||||
buf[1][h]=os[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,8 +502,8 @@ void DivPlatformSegaPCM::setFlags(const DivConfig& flags) {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformSegaPCM::isStereo() {
|
||||
return true;
|
||||
int DivPlatformSegaPCM::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
int DivPlatformSegaPCM::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
|
||||
|
|
|
@ -77,7 +77,7 @@ class DivPlatformSegaPCM: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -91,7 +91,7 @@ class DivPlatformSegaPCM: public DivDispatch {
|
|||
void notifyInsChange(int ins);
|
||||
void renderSamples(int chipID);
|
||||
void setFlags(const DivConfig& flags);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
||||
|
|
|
@ -39,10 +39,10 @@ const char** DivPlatformSMS::getRegisterSheet() {
|
|||
return stereo?regCheatSheetGG:regCheatSheetSN;
|
||||
}
|
||||
|
||||
void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSMS::acquire_nuked(short** buf, size_t len) {
|
||||
int oL=0;
|
||||
int oR=0;
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
if (w.addr==0) {
|
||||
|
@ -73,8 +73,8 @@ void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
if (oL>32767) oL=32767;
|
||||
if (oR<-32768) oR=-32768;
|
||||
if (oR>32767) oR=32767;
|
||||
bufL[h]=oL;
|
||||
bufR[h]=oR;
|
||||
buf[0][h]=oL;
|
||||
if (stereo) buf[1][h]=oR;
|
||||
for (int i=0; i<4; i++) {
|
||||
if (isMuted[i]) {
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=0;
|
||||
|
@ -85,7 +85,7 @@ void DivPlatformSMS::acquire_nuked(short* bufL, short* bufR, size_t start, size_
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSMS::acquire_mame(short** buf, size_t len) {
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
if (stereo && (w.addr==1))
|
||||
|
@ -95,10 +95,10 @@ void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t
|
|||
}
|
||||
writes.pop();
|
||||
}
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
short* outs[2]={
|
||||
&bufL[h],
|
||||
&bufR[h]
|
||||
&buf[0][h],
|
||||
stereo?(&buf[1][h]):NULL
|
||||
};
|
||||
sn->sound_stream_update(outs,1);
|
||||
for (int i=0; i<4; i++) {
|
||||
|
@ -111,11 +111,11 @@ void DivPlatformSMS::acquire_mame(short* bufL, short* bufR, size_t start, size_t
|
|||
}
|
||||
}
|
||||
|
||||
void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSMS::acquire(short** buf, size_t len) {
|
||||
if (nuked) {
|
||||
acquire_nuked(bufL,bufR,start,len);
|
||||
acquire_nuked(buf,len);
|
||||
} else {
|
||||
acquire_mame(bufL,bufR,start,len);
|
||||
acquire_mame(buf,len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,8 +445,8 @@ void DivPlatformSMS::reset() {
|
|||
}
|
||||
}
|
||||
|
||||
bool DivPlatformSMS::isStereo() {
|
||||
return stereo;
|
||||
int DivPlatformSMS::getOutputCount() {
|
||||
return stereo?2:1;
|
||||
}
|
||||
|
||||
bool DivPlatformSMS::keyOffAffectsArp(int ch) {
|
||||
|
|
|
@ -66,10 +66,10 @@ class DivPlatformSMS: public DivDispatch {
|
|||
double NOTE_SN(int ch, int note);
|
||||
int snCalcFreq(int ch);
|
||||
|
||||
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_mame(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire_nuked(short** buf, size_t len);
|
||||
void acquire_mame(short** buf, size_t len);
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -78,7 +78,7 @@ class DivPlatformSMS: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
int getPortaFloor(int ch);
|
||||
|
|
|
@ -65,10 +65,10 @@ const char** DivPlatformSNES::getRegisterSheet() {
|
|||
return regCheatSheetSNESDSP;
|
||||
}
|
||||
|
||||
void DivPlatformSNES::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||
void DivPlatformSNES::acquire(short** buf, size_t len) {
|
||||
short out[2];
|
||||
short chOut[16];
|
||||
for (size_t h=start; h<start+len; h++) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
if (--delay<=0) {
|
||||
delay=0;
|
||||
if (!writes.empty()) {
|
||||
|
@ -82,8 +82,8 @@ void DivPlatformSNES::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
dsp.set_output(out,1);
|
||||
dsp.run(32);
|
||||
dsp.get_voice_outputs(chOut);
|
||||
bufL[h]=out[0];
|
||||
bufR[h]=out[1];
|
||||
buf[0][h]=out[0];
|
||||
buf[1][h]=out[1];
|
||||
for (int i=0; i<8; i++) {
|
||||
int next=(3*(chOut[i*2]+chOut[i*2+1]))>>2;
|
||||
if (next<-32768) next=-32768;
|
||||
|
@ -768,8 +768,8 @@ void DivPlatformSNES::reset() {
|
|||
initEcho();
|
||||
}
|
||||
|
||||
bool DivPlatformSNES::isStereo() {
|
||||
return true;
|
||||
int DivPlatformSNES::getOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void DivPlatformSNES::notifyInsChange(int ins) {
|
||||
|
|
|
@ -93,7 +93,7 @@ class DivPlatformSNES: public DivDispatch {
|
|||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
@ -104,7 +104,7 @@ class DivPlatformSNES: public DivDispatch {
|
|||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool isStereo();
|
||||
int getOutputCount();
|
||||
void notifyInsChange(int ins);
|
||||
void notifyWaveChange(int wave);
|
||||
void setFlags(const DivConfig& flags);
|
||||
|
|
|
@ -1064,12 +1064,11 @@ void ay8910_device::sound_stream_update(short** outputs, int outLen)
|
|||
tone = &m_tone[chan];
|
||||
const int period = std::max<int>(1, tone->period) * (m_step_mul << 1);
|
||||
tone->count += is_expanded_mode() ? 32 : ((m_feature & PSG_HAS_EXPANDED_MODE) ? 1 : 2);
|
||||
while (tone->count >= period)
|
||||
{
|
||||
tone->duty_cycle = (tone->duty_cycle - 1) & 0x1f;
|
||||
tone->output = is_expanded_mode() ? BIT(duty_cycle[tone_duty(tone)], tone->duty_cycle) : BIT(tone->duty_cycle, 0);
|
||||
tone->count -= period;
|
||||
}
|
||||
if (tone->count>=period) {
|
||||
tone->duty_cycle = (tone->duty_cycle - (tone->count/period)) & 0x1f;
|
||||
tone->output = is_expanded_mode() ? BIT(duty_cycle[tone_duty(tone)], tone->duty_cycle) : BIT(tone->duty_cycle, 0);
|
||||
tone->count = tone->count % period;
|
||||
}
|
||||
}
|
||||
|
||||
const int period_noise = (int)(noise_period()) * m_step_mul;
|
||||
|
|
|
@ -659,11 +659,13 @@ void namco_audio_device::sound_stream_update(short** outputs, int len)
|
|||
{
|
||||
lmix[i]+=l_noise_data;
|
||||
rmix[i]+=r_noise_data;
|
||||
voice->last_out=(l_noise_data+r_noise_data)>>1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lmix[i]+=-l_noise_data;
|
||||
rmix[i]+=-r_noise_data;
|
||||
voice->last_out=-((l_noise_data+r_noise_data)>>1);
|
||||
}
|
||||
|
||||
if (hold)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue