Updated ft2play and fixed up dbopl
This commit is contained in:
parent
0839cbbd9d
commit
55eec18bfe
3 changed files with 189 additions and 166 deletions
|
@ -38,9 +38,159 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
//#include "dosbox.h"
|
|
||||||
#include "dbopl.h"
|
#include "dbopl.h"
|
||||||
|
|
||||||
|
//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
|
||||||
|
#define WAVE_HANDLER 10
|
||||||
|
//Use a logarithmic wavetable with an exponential table for volume
|
||||||
|
#define WAVE_TABLELOG 11
|
||||||
|
//Use a linear wavetable with a multiply table for volume
|
||||||
|
#define WAVE_TABLEMUL 12
|
||||||
|
|
||||||
|
//Select the type of wave generator routine
|
||||||
|
#define DBOPL_WAVE WAVE_TABLEMUL
|
||||||
|
|
||||||
|
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||||
|
typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Operator Operator;
|
||||||
|
typedef struct Channel Channel;
|
||||||
|
typedef struct Chip Chip;
|
||||||
|
|
||||||
|
typedef Bits ( *Operator_VolumeHandler) ( struct Operator * );
|
||||||
|
typedef struct Channel* ( *Channel_SynthHandler) ( struct Channel *, struct Chip* chip, Bit32u samples, Bit32s* output );
|
||||||
|
|
||||||
|
//Different synth modes that can generate blocks of data
|
||||||
|
typedef enum {
|
||||||
|
sm2AM,
|
||||||
|
sm2FM,
|
||||||
|
sm3AM,
|
||||||
|
sm3FM,
|
||||||
|
sm4Start,
|
||||||
|
sm3FMFM,
|
||||||
|
sm3AMFM,
|
||||||
|
sm3FMAM,
|
||||||
|
sm3AMAM,
|
||||||
|
sm6Start,
|
||||||
|
sm2Percussion,
|
||||||
|
sm3Percussion
|
||||||
|
} SynthMode;
|
||||||
|
|
||||||
|
//Shifts for the values contained in chandata variable
|
||||||
|
enum {
|
||||||
|
SHIFT_KSLBASE = 16,
|
||||||
|
SHIFT_KEYCODE = 24
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MASK_KSR = 0x10,
|
||||||
|
MASK_SUSTAIN = 0x20,
|
||||||
|
MASK_VIBRATO = 0x40,
|
||||||
|
MASK_TREMOLO = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OFF,
|
||||||
|
RELEASE,
|
||||||
|
SUSTAIN,
|
||||||
|
DECAY,
|
||||||
|
ATTACK
|
||||||
|
} Operator_State;
|
||||||
|
|
||||||
|
struct Operator {
|
||||||
|
//Masks for operator 20 values
|
||||||
|
Operator_VolumeHandler volHandler;
|
||||||
|
|
||||||
|
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||||
|
WaveHandler waveHandler; //Routine that generate a wave
|
||||||
|
#else
|
||||||
|
Bit16s* waveBase;
|
||||||
|
Bit32u waveMask;
|
||||||
|
Bit32u waveStart;
|
||||||
|
#endif
|
||||||
|
Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
|
||||||
|
Bit32u waveAdd; //The base frequency without vibrato
|
||||||
|
Bit32u waveCurrent; //waveAdd + vibratao
|
||||||
|
|
||||||
|
Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
|
||||||
|
Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
|
||||||
|
Bit32u vibrato; //Scaled up vibrato strength
|
||||||
|
Bit32s sustainLevel; //When stopping at sustain level stop here
|
||||||
|
Bit32s totalLevel; //totalLevel is added to every generated volume
|
||||||
|
Bit32u currentLevel; //totalLevel + tremolo
|
||||||
|
Bit32s volume; //The currently active volume
|
||||||
|
|
||||||
|
Bit32u attackAdd; //Timers for the different states of the envelope
|
||||||
|
Bit32u decayAdd;
|
||||||
|
Bit32u releaseAdd;
|
||||||
|
Bit32u rateIndex; //Current position of the evenlope
|
||||||
|
|
||||||
|
Bit8u rateZero; //Bits for the different states of the envelope having no changes
|
||||||
|
Bit8u keyOn; //Bitmask of different values that can generate keyon
|
||||||
|
//Registers, also used to check for changes
|
||||||
|
Bit8u reg20, reg40, reg60, reg80, regE0;
|
||||||
|
//Active part of the envelope we're in
|
||||||
|
Bit8u state;
|
||||||
|
//0xff when tremolo is enabled
|
||||||
|
Bit8u tremoloMask;
|
||||||
|
//Strength of the vibrato
|
||||||
|
Bit8u vibStrength;
|
||||||
|
//Keep track of the calculated KSR so we can check for changes
|
||||||
|
Bit8u ksr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Channel {
|
||||||
|
struct Operator op[2];
|
||||||
|
Channel_SynthHandler synthHandler;
|
||||||
|
Bit32u chanData; //Frequency/octave and derived values
|
||||||
|
Bit32s old[2]; //Old data for feedback
|
||||||
|
|
||||||
|
Bit8u feedback; //Feedback shift
|
||||||
|
Bit8u regB0; //Register values to check for changes
|
||||||
|
Bit8u regC0;
|
||||||
|
//This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
|
||||||
|
Bit8u fourMask;
|
||||||
|
Bit8s maskLeft; //Sign extended values for both channel's panning
|
||||||
|
Bit8s maskRight;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Chip {
|
||||||
|
//This is used as the base counter for vibrato and tremolo
|
||||||
|
Bit32u lfoCounter;
|
||||||
|
Bit32u lfoAdd;
|
||||||
|
|
||||||
|
|
||||||
|
Bit32u noiseCounter;
|
||||||
|
Bit32u noiseAdd;
|
||||||
|
Bit32u noiseValue;
|
||||||
|
|
||||||
|
//Frequency scales for the different multiplications
|
||||||
|
Bit32u freqMul[16];
|
||||||
|
//Rates for decay and release for rate of this chip
|
||||||
|
Bit32u linearRates[76];
|
||||||
|
//Best match attack rates for the rate of this chip
|
||||||
|
Bit32u attackRates[76];
|
||||||
|
|
||||||
|
//18 channels with 2 operators each
|
||||||
|
struct Channel chan[18];
|
||||||
|
|
||||||
|
Bit8u reg104;
|
||||||
|
Bit8u reg08;
|
||||||
|
Bit8u reg04;
|
||||||
|
Bit8u regBD;
|
||||||
|
Bit8u vibratoIndex;
|
||||||
|
Bit8u tremoloIndex;
|
||||||
|
Bit8s vibratoSign;
|
||||||
|
Bit8u vibratoShift;
|
||||||
|
Bit8u tremoloValue;
|
||||||
|
Bit8u vibratoStrength;
|
||||||
|
Bit8u tremoloStrength;
|
||||||
|
//Mask for allowed wave forms
|
||||||
|
Bit8u waveFormMask;
|
||||||
|
//0 or -1 when enabled
|
||||||
|
Bit8s opl3Active;
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef PI
|
#ifndef PI
|
||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
|
@ -905,8 +1055,8 @@ static Bit32s Channel_GeneratePercussion( struct Channel *chan, struct Chip* chi
|
||||||
|
|
||||||
//Precalculate stuff used by other outputs
|
//Precalculate stuff used by other outputs
|
||||||
noiseBit = Chip_ForwardNoise( chip ) & 0x1;
|
noiseBit = Chip_ForwardNoise( chip ) & 0x1;
|
||||||
c2 = Operator_ForwardWave( Channel_Operator( chan, 2 ) );
|
c2 = Operator_ForwardWave( Channel_Op( chan, 2 ) );
|
||||||
c5 = Operator_ForwardWave( Channel_Operator( chan, 5 ) );
|
c5 = Operator_ForwardWave( Channel_Op( chan, 5 ) );
|
||||||
phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
|
phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00;
|
||||||
|
|
||||||
//Hi-Hat
|
//Hi-Hat
|
||||||
|
@ -1136,10 +1286,16 @@ static void Channel_ResetC0( struct Channel *c, const struct Chip* chip ) {
|
||||||
Chip
|
Chip
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
Bitu Chip_GetSize()
|
||||||
|
{
|
||||||
|
return sizeof(struct Chip);
|
||||||
|
}
|
||||||
|
|
||||||
static void InitTables( void );
|
static void InitTables( void );
|
||||||
|
|
||||||
void Chip_Init(struct Chip *chip) {
|
void Chip_Init(void *_chip) {
|
||||||
Bit32u i;
|
Bit32u i;
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
InitTables();
|
InitTables();
|
||||||
chip->reg08 = 0;
|
chip->reg08 = 0;
|
||||||
chip->reg04 = 0;
|
chip->reg04 = 0;
|
||||||
|
@ -1267,8 +1423,9 @@ static void Chip_WriteBD( struct Chip *chip, Bit8u val ) {
|
||||||
Channel_##_FUNC_( regChan, chip, val ); \
|
Channel_##_FUNC_( regChan, chip, val ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip_WriteReg( struct Chip *chip, Bit32u reg, Bit8u val ) {
|
void Chip_WriteReg( void *_chip, Bit32u reg, Bit8u val ) {
|
||||||
Bitu index;
|
Bitu index;
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
switch ( (reg & 0xf0) >> 4 ) {
|
switch ( (reg & 0xf0) >> 4 ) {
|
||||||
case 0x00 >> 4:
|
case 0x00 >> 4:
|
||||||
if ( reg == 0x01 ) {
|
if ( reg == 0x01 ) {
|
||||||
|
@ -1330,7 +1487,8 @@ void Chip_WriteReg( struct Chip *chip, Bit32u reg, Bit8u val ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit32u Chip_WriteAddr( struct Chip *chip, Bit32u port, Bit8u val ) {
|
Bit32u Chip_WriteAddr( void *_chip, Bit32u port, Bit8u val ) {
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
switch ( port & 3 ) {
|
switch ( port & 3 ) {
|
||||||
case 0:
|
case 0:
|
||||||
return val;
|
return val;
|
||||||
|
@ -1343,7 +1501,8 @@ Bit32u Chip_WriteAddr( struct Chip *chip, Bit32u port, Bit8u val ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip_GenerateBlock2( struct Chip *chip, Bitu total, Bit32s* output ) {
|
void Chip_GenerateBlock2( void *_chip, Bitu total, Bit32s* output ) {
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
while ( total > 0 ) {
|
while ( total > 0 ) {
|
||||||
struct Channel* ch;
|
struct Channel* ch;
|
||||||
int count;
|
int count;
|
||||||
|
@ -1361,11 +1520,12 @@ void Chip_GenerateBlock2( struct Chip *chip, Bitu total, Bit32s* output ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip_GenerateBlock3( struct Chip *chip, Bitu total, Bit32s* output ) {
|
void Chip_GenerateBlock3( void *_chip, Bitu total, Bit32s* output ) {
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
while ( total > 0 ) {
|
while ( total > 0 ) {
|
||||||
struct Channel* ch;
|
struct Channel* ch;
|
||||||
int count;
|
int count;
|
||||||
Bit32u samples = ForwardLFO( total );
|
Bit32u samples = Chip_ForwardLFO( chip, total );
|
||||||
for ( Bitu i = 0; i < samples; i++ ) {
|
for ( Bitu i = 0; i < samples; i++ ) {
|
||||||
output[i * 2 + 0 ] = 0;
|
output[i * 2 + 0 ] = 0;
|
||||||
output[i * 2 + 1 ] = 0;
|
output[i * 2 + 1 ] = 0;
|
||||||
|
@ -1380,7 +1540,8 @@ void Chip_GenerateBlock3( struct Chip *chip, Bitu total, Bit32s* output ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chip_Setup( struct Chip *chip, Bit32u clock, Bit32u rate ) {
|
void Chip_Setup( void *_chip, Bit32u clock, Bit32u rate ) {
|
||||||
|
struct Chip *chip = (struct Chip *)_chip;
|
||||||
double original = (double)clock / 288.0;
|
double original = (double)clock / 288.0;
|
||||||
double scale = original / (double)rate;
|
double scale = original / (double)rate;
|
||||||
if (fabs(scale - 1.0) < 0.00001)
|
if (fabs(scale - 1.0) < 0.00001)
|
||||||
|
|
|
@ -57,161 +57,13 @@ typedef signed long long Bit64s;
|
||||||
typedef unsigned int Bitu;
|
typedef unsigned int Bitu;
|
||||||
typedef signed int Bits;
|
typedef signed int Bits;
|
||||||
|
|
||||||
//#include "dosbox.h"
|
Bitu Chip_GetSize();
|
||||||
|
|
||||||
//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
|
void Chip_Init( void *chip );
|
||||||
#define WAVE_HANDLER 10
|
void Chip_Setup( void *chip, Bit32u clock, Bit32u rate );
|
||||||
//Use a logarithmic wavetable with an exponential table for volume
|
|
||||||
#define WAVE_TABLELOG 11
|
|
||||||
//Use a linear wavetable with a multiply table for volume
|
|
||||||
#define WAVE_TABLEMUL 12
|
|
||||||
|
|
||||||
//Select the type of wave generator routine
|
void Chip_WriteReg( void *chip, Bit32u reg, Bit8u val );
|
||||||
#define DBOPL_WAVE WAVE_TABLEMUL
|
Bit32u Chip_WriteAddr( void *chip, Bit32u port, Bit8u val );
|
||||||
|
|
||||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
void Chip_GenerateBlock2( void *chip, Bitu total, Bit32s* output );
|
||||||
typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
|
void Chip_GenerateBlock3( void *chip, Bitu total, Bit32s* output );
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef Bits ( *Operator_VolumeHandler) ( struct Operator * );
|
|
||||||
typedef struct Channel* ( *Channel_SynthHandler) ( struct Channel *, struct Chip* chip, Bit32u samples, Bit32s* output );
|
|
||||||
|
|
||||||
//Different synth modes that can generate blocks of data
|
|
||||||
typedef enum {
|
|
||||||
sm2AM,
|
|
||||||
sm2FM,
|
|
||||||
sm3AM,
|
|
||||||
sm3FM,
|
|
||||||
sm4Start,
|
|
||||||
sm3FMFM,
|
|
||||||
sm3AMFM,
|
|
||||||
sm3FMAM,
|
|
||||||
sm3AMAM,
|
|
||||||
sm6Start,
|
|
||||||
sm2Percussion,
|
|
||||||
sm3Percussion
|
|
||||||
} SynthMode;
|
|
||||||
|
|
||||||
//Shifts for the values contained in chandata variable
|
|
||||||
enum {
|
|
||||||
SHIFT_KSLBASE = 16,
|
|
||||||
SHIFT_KEYCODE = 24
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
MASK_KSR = 0x10,
|
|
||||||
MASK_SUSTAIN = 0x20,
|
|
||||||
MASK_VIBRATO = 0x40,
|
|
||||||
MASK_TREMOLO = 0x80
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
OFF,
|
|
||||||
RELEASE,
|
|
||||||
SUSTAIN,
|
|
||||||
DECAY,
|
|
||||||
ATTACK
|
|
||||||
} Operator_State;
|
|
||||||
|
|
||||||
struct Operator {
|
|
||||||
//Masks for operator 20 values
|
|
||||||
Operator_VolumeHandler volHandler;
|
|
||||||
|
|
||||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
|
||||||
WaveHandler waveHandler; //Routine that generate a wave
|
|
||||||
#else
|
|
||||||
Bit16s* waveBase;
|
|
||||||
Bit32u waveMask;
|
|
||||||
Bit32u waveStart;
|
|
||||||
#endif
|
|
||||||
Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
|
|
||||||
Bit32u waveAdd; //The base frequency without vibrato
|
|
||||||
Bit32u waveCurrent; //waveAdd + vibratao
|
|
||||||
|
|
||||||
Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
|
|
||||||
Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
|
|
||||||
Bit32u vibrato; //Scaled up vibrato strength
|
|
||||||
Bit32s sustainLevel; //When stopping at sustain level stop here
|
|
||||||
Bit32s totalLevel; //totalLevel is added to every generated volume
|
|
||||||
Bit32u currentLevel; //totalLevel + tremolo
|
|
||||||
Bit32s volume; //The currently active volume
|
|
||||||
|
|
||||||
Bit32u attackAdd; //Timers for the different states of the envelope
|
|
||||||
Bit32u decayAdd;
|
|
||||||
Bit32u releaseAdd;
|
|
||||||
Bit32u rateIndex; //Current position of the evenlope
|
|
||||||
|
|
||||||
Bit8u rateZero; //Bits for the different states of the envelope having no changes
|
|
||||||
Bit8u keyOn; //Bitmask of different values that can generate keyon
|
|
||||||
//Registers, also used to check for changes
|
|
||||||
Bit8u reg20, reg40, reg60, reg80, regE0;
|
|
||||||
//Active part of the envelope we're in
|
|
||||||
Bit8u state;
|
|
||||||
//0xff when tremolo is enabled
|
|
||||||
Bit8u tremoloMask;
|
|
||||||
//Strength of the vibrato
|
|
||||||
Bit8u vibStrength;
|
|
||||||
//Keep track of the calculated KSR so we can check for changes
|
|
||||||
Bit8u ksr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Channel {
|
|
||||||
struct Operator op[2];
|
|
||||||
Channel_SynthHandler synthHandler;
|
|
||||||
Bit32u chanData; //Frequency/octave and derived values
|
|
||||||
Bit32s old[2]; //Old data for feedback
|
|
||||||
|
|
||||||
Bit8u feedback; //Feedback shift
|
|
||||||
Bit8u regB0; //Register values to check for changes
|
|
||||||
Bit8u regC0;
|
|
||||||
//This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
|
|
||||||
Bit8u fourMask;
|
|
||||||
Bit8s maskLeft; //Sign extended values for both channel's panning
|
|
||||||
Bit8s maskRight;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Chip {
|
|
||||||
//This is used as the base counter for vibrato and tremolo
|
|
||||||
Bit32u lfoCounter;
|
|
||||||
Bit32u lfoAdd;
|
|
||||||
|
|
||||||
|
|
||||||
Bit32u noiseCounter;
|
|
||||||
Bit32u noiseAdd;
|
|
||||||
Bit32u noiseValue;
|
|
||||||
|
|
||||||
//Frequency scales for the different multiplications
|
|
||||||
Bit32u freqMul[16];
|
|
||||||
//Rates for decay and release for rate of this chip
|
|
||||||
Bit32u linearRates[76];
|
|
||||||
//Best match attack rates for the rate of this chip
|
|
||||||
Bit32u attackRates[76];
|
|
||||||
|
|
||||||
//18 channels with 2 operators each
|
|
||||||
struct Channel chan[18];
|
|
||||||
|
|
||||||
Bit8u reg104;
|
|
||||||
Bit8u reg08;
|
|
||||||
Bit8u reg04;
|
|
||||||
Bit8u regBD;
|
|
||||||
Bit8u vibratoIndex;
|
|
||||||
Bit8u tremoloIndex;
|
|
||||||
Bit8s vibratoSign;
|
|
||||||
Bit8u vibratoShift;
|
|
||||||
Bit8u tremoloValue;
|
|
||||||
Bit8u vibratoStrength;
|
|
||||||
Bit8u tremoloStrength;
|
|
||||||
//Mask for allowed wave forms
|
|
||||||
Bit8u waveFormMask;
|
|
||||||
//0 or -1 when enabled
|
|
||||||
Bit8s opl3Active;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Chip_Init(struct Chip *chip);
|
|
||||||
void Chip_Setup( struct Chip *chip, Bit32u clock, Bit32u rate );
|
|
||||||
|
|
||||||
void Chip_WriteReg( struct Chip *chip, Bit32u reg, Bit8u val );
|
|
||||||
Bit32u Chip_WriteAddr( struct Chip *chip, Bit32u port, Bit8u val );
|
|
||||||
|
|
||||||
void Chip_GenerateBlock2( struct Chip *chip, Bitu total, Bit32s* output );
|
|
||||||
void Chip_GenerateBlock3( struct Chip *chip, Bitu total, Bit32s* output );
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
** It's just an accurate FastTracker II replayer port for people to enjoy.
|
** It's just an accurate FastTracker II replayer port for people to enjoy.
|
||||||
**
|
**
|
||||||
**
|
**
|
||||||
|
** non-FT2 effects:
|
||||||
|
** - E8x - set panning
|
||||||
|
**
|
||||||
** (extreme) non-FT2 extensions:
|
** (extreme) non-FT2 extensions:
|
||||||
** - Max 127 channels (was 32)
|
** - Max 127 channels (was 32)
|
||||||
** - Any amount-of-channels number (FT2 supports *even* numbers only)
|
** - Any amount-of-channels number (FT2 supports *even* numbers only)
|
||||||
|
@ -966,7 +969,14 @@ CheckEffects:
|
||||||
|
|
||||||
// E7x - set tremolo waveform
|
// E7x - set tremolo waveform
|
||||||
else if ((ch->Eff & 0xF0) == 0x70) ch->WaveCtrl = ((ch->Eff & 0x0F) << 4) | (ch->WaveCtrl & 0x0F);
|
else if ((ch->Eff & 0xF0) == 0x70) ch->WaveCtrl = ((ch->Eff & 0x0F) << 4) | (ch->WaveCtrl & 0x0F);
|
||||||
|
|
||||||
|
// E8x - set panning - *non-FT2*
|
||||||
|
else if ((ch->Eff & 0xF0) == 0x80)
|
||||||
|
{
|
||||||
|
ch->OutPan = (ch->Eff & 0x0F) << 4;
|
||||||
|
ch->Status |= IS_Pan;
|
||||||
|
}
|
||||||
|
|
||||||
// EAx - fine volume slide up
|
// EAx - fine volume slide up
|
||||||
else if ((ch->Eff & 0xF0) == 0xA0)
|
else if ((ch->Eff & 0xF0) == 0xA0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue