Updated modplay

CQTexperiment
Chris Moeller 2014-04-01 14:12:54 -07:00
parent 52e8c8f07d
commit 3264ce9154
4 changed files with 88 additions and 90 deletions

View File

@ -1512,7 +1512,7 @@ void Chip_WriteReg( void *_chip, Bit32u reg, Bit8u val ) {
}
}
Bit32u Chip_WriteAddr( void *_chip, Bit32u port, Bit8u val ) {
Bit32u Chip_WriteAddr( struct Chip *_chip, Bit32u port, Bit8u val ) {
struct Chip *chip = (struct Chip *)_chip;
switch ( port & 3 ) {
case 0:
@ -1526,8 +1526,7 @@ Bit32u Chip_WriteAddr( void *_chip, Bit32u port, Bit8u val ) {
return 0;
}
void Chip_GenerateBlock2( void *_chip, Bitu total, Bit32s* output ) {
struct Chip *chip = (struct Chip *)_chip;
static void Chip_GenerateBlock2( struct Chip *chip, Bitu total, Bit32s* output ) {
while ( total > 0 ) {
struct Channel* ch;
int count;
@ -1546,8 +1545,7 @@ void Chip_GenerateBlock2( void *_chip, Bitu total, Bit32s* output ) {
}
}
void Chip_GenerateBlock3( void *_chip, Bitu total, Bit32s* output ) {
struct Chip *chip = (struct Chip *)_chip;
static void Chip_GenerateBlock3( struct Chip *chip, Bitu total, Bit32s* output ) {
while ( total > 0 ) {
struct Channel* ch;
int count;
@ -1567,6 +1565,34 @@ void Chip_GenerateBlock3( void *_chip, Bitu total, Bit32s* output ) {
}
}
void Chip_GenerateBlock_Mono( void *_chip, Bitu total, Bit32s* output ) {
struct Chip *chip = (struct Chip *)_chip;
if (chip->opl3Active) {
while ( total > 0 ) {
Bit32s temp[512];
Bitu todo = ( total > 256 ) ? 256 : total, i;
Chip_GenerateBlock3( chip, todo, temp );
total -= todo;
todo *= 2;
for ( i = 0; i < todo; i += 2 ) {
*output++ = (temp[i] + temp[i + 1]) >> 1;
}
}
} else
Chip_GenerateBlock2( chip, total, output );
}
void Chip_GenerateBlock_Stereo( void *_chip, Bitu total, Bit32s* output) {
struct Chip *chip = (struct Chip *)_chip;
if (!chip->opl3Active) {
Chip_GenerateBlock2( chip, total, output );
while ( total-- ) {
output[total * 2 + 1] = output[total * 2] = output[total];
}
} else
Chip_GenerateBlock3( chip, total, output );
}
void Chip_Setup( void *_chip, Bit32u clock, Bit32u rate ) {
struct Chip *chip = (struct Chip *)_chip;
double original = (double)clock / 288.0;

View File

@ -65,5 +65,5 @@ void Chip_Setup( void *chip, Bit32u clock, Bit32u rate );
void Chip_WriteReg( void *chip, Bit32u reg, Bit8u val );
Bit32u Chip_WriteAddr( void *chip, Bit32u port, Bit8u val );
void Chip_GenerateBlock2( void *chip, Bitu total, Bit32s* output );
void Chip_GenerateBlock3( void *chip, Bitu total, Bit32s* output );
void Chip_GenerateBlock_Mono( void *chip, Bitu total, Bit32s* output );
void Chip_GenerateBlock_Stereo( void *chip, Bitu total, Bit32s* output );

View File

@ -1,5 +1,5 @@
/*
** FT2PLAY v0.40a
** FT2PLAY v0.42a
** ==============
**
** C port of FastTracker II's replayer, by 8bitbubsy (Olav Sørensen)
@ -426,7 +426,7 @@ static void voiceSetSource(PLAYER *, uint8_t i, const int8_t *sampleData,
static void voiceSetSamplePosition(PLAYER *, uint8_t i, uint16_t value);
static void voiceSetVolume(PLAYER *, uint8_t i, float vol, uint8_t sharp);
void voiceSetPanning(PLAYER *, uint8_t i, uint8_t pan);
static void voiceSetSamplingFrequency(PLAYER *, uint8_t i, float samplingFrequency);
static void voiceSetSamplingFrequency(PLAYER *, uint8_t i, uint32_t samplingFrequency);
// TABLES AND VARIABLES
@ -444,7 +444,7 @@ static const uint16_t AmigaFinePeriod[12 * 8] =
494,491,487,484,480,477,474,470,467,463,460,457
};
// This table'a data is so small that generating it makes no sense
// This table is so small that generating it is almost as big
static const uint8_t VibTab[32] =
{
0, 24, 49, 74, 97,120,141,161,
@ -568,13 +568,13 @@ static void StartTone(PLAYER *p, uint8_t Ton, uint8_t EffTyp, uint8_t Eff, StmTy
}
// ------------------------------------------------------------
ch->TonNr = Ton;
if (p->Instr[ch->InstrNr] != NULL)
ch->InstrSeg = *p->Instr[ch->InstrNr];
else
ch->InstrSeg = *p->Instr[0]; // placeholder for invalid samples
ch->TonNr = Ton;
// non-FT2 security fix
tonLookUp = Ton - 1;
if (tonLookUp > 95) tonLookUp = 95;
@ -654,7 +654,7 @@ static void MultiRetrig(PLAYER *p, StmTyp *ch)
else if (cmd == 0x03) vol -= 4;
else if (cmd == 0x04) vol -= 8;
else if (cmd == 0x05) vol -= 16;
else if (cmd == 0x06) vol = (vol >> 1) + (vol >> 2) + (vol >> 3);
else if (cmd == 0x06) vol = (vol >> 1) + (vol >> 3) + (vol >> 4);
else if (cmd == 0x07) vol >>= 1;
else if (cmd == 0x09) vol += 1;
else if (cmd == 0x0A) vol += 2;
@ -672,8 +672,8 @@ static void MultiRetrig(PLAYER *p, StmTyp *ch)
if ((ch->VolKolVol >= 0x10) && (ch->VolKolVol <= 0x50))
{
ch->RealVol = ch->VolKolVol - 16;
ch->OutVol = ch->RealVol;
ch->OutVol = ch->VolKolVol - 0x10;
ch->RealVol = ch->OutVol;
}
else if ((ch->VolKolVol >= 0xC0) && (ch->VolKolVol <= 0xCF))
{
@ -821,8 +821,9 @@ CheckEffects:
// set volume
if ((ch->VolKolVol >= 0x10) && (ch->VolKolVol <= 0x50))
{
ch->RealVol = ch->VolKolVol - 0x10;
ch->OutVol = ch->RealVol;
ch->OutVol = ch->VolKolVol - 0x10;
ch->RealVol = ch->OutVol;
ch->Status |= IS_Vol;
}
@ -2060,7 +2061,7 @@ static void MainPlayer(PLAYER *p) // periodically called from mixer
voiceSetPanning(p, ch->Nr, ch->FinalPan);
if (ch->Status & IS_Period)
voiceSetSamplingFrequency(p, ch->Nr, (float)(GetFrequenceValue(p, ch->FinalPeriod)));
voiceSetSamplingFrequency(p, ch->Nr, GetFrequenceValue(p, ch->FinalPeriod));
if (ch->Status & IS_NyTon)
{
@ -2824,9 +2825,9 @@ void voiceSetPanning(PLAYER *p, uint8_t i, uint8_t pan)
#endif
}
void voiceSetSamplingFrequency(PLAYER *p, uint8_t i, float samplingFrequency)
void voiceSetSamplingFrequency(PLAYER *p, uint8_t i, uint32_t samplingFrequency)
{
p->voice[i].incRate = samplingFrequency / p->f_outputFreq;
p->voice[i].incRate = (float)(samplingFrequency) / p->f_outputFreq;
}
static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
@ -2882,14 +2883,9 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
resampler_write_sample(resampler, sampleData[samplePosition] * 256);
if (loopDir == 1)
{
if (--samplePosition < 0)
samplePosition = 0;
}
--samplePosition;
else
{
++samplePosition;
}
if (loopEnabled)
{
@ -2899,7 +2895,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition <= sampleLoopBegin)
{
samplePosition += (sampleLoopBegin - samplePosition) - 1;
samplePosition = sampleLoopBegin + (sampleLoopBegin - samplePosition);
loopDir = 0;
}
}
@ -2907,7 +2903,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition >= sampleLoopEnd)
{
samplePosition -= (samplePosition - sampleLoopEnd) + 1;
samplePosition = sampleLoopEnd - (samplePosition - sampleLoopEnd);
loopDir = 1;
}
}
@ -2915,10 +2911,10 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
else
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
}
else if (samplePosition >= sampleLength)
else if ((samplePosition < 0) || (samplePosition >= sampleLength))
{
interpolating = 0;
break;
@ -2932,7 +2928,6 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples)
if ( !resampler_ready(resampler) )
{
p->voice[ch].sampleData = NULL;
p->voice[ch].samplePosition = 0;
p->voice[ch].busy = 0;
break;
}
@ -3059,14 +3054,9 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition] * 256);
if (loopDir == 1)
{
if (--samplePosition < 0)
samplePosition = 0;
}
--samplePosition;
else
{
++samplePosition;
}
if (loopEnabled)
{
@ -3076,7 +3066,7 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition <= sampleLoopBegin)
{
samplePosition += (sampleLoopBegin - samplePosition) - 1;
samplePosition = sampleLoopBegin + (sampleLoopBegin - samplePosition);
loopDir = 0;
}
}
@ -3084,7 +3074,7 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition >= sampleLoopEnd)
{
samplePosition -= (samplePosition - sampleLoopEnd) + 1;
samplePosition = sampleLoopEnd - (samplePosition - sampleLoopEnd);
loopDir = 1;
}
}
@ -3092,10 +3082,10 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
else
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
}
else if (samplePosition >= sampleLength)
else if ((samplePosition < 0) || (samplePosition >= sampleLength))
{
interpolating = 0;
break;
@ -3109,7 +3099,6 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
if ( !resampler_ready(resampler[0]) )
{
p->voice[ch].sampleData = NULL;
p->voice[ch].samplePosition = 0;
p->voice[ch].busy = 0;
break;
}
@ -3233,14 +3222,9 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
resampler_write_sample(resampler, sampleData[samplePosition]);
if (loopDir == 1)
{
if (--samplePosition < 0)
samplePosition = 0;
}
--samplePosition;
else
{
++samplePosition;
}
if (loopEnabled)
{
@ -3250,7 +3234,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition <= sampleLoopBegin)
{
samplePosition += (sampleLoopBegin - samplePosition) - 1;
samplePosition = sampleLoopBegin + (sampleLoopBegin - samplePosition);
loopDir = 0;
}
}
@ -3258,7 +3242,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition >= sampleLoopEnd)
{
samplePosition -= (samplePosition - sampleLoopEnd) + 1;
samplePosition = sampleLoopEnd - (samplePosition - sampleLoopEnd);
loopDir = 1;
}
}
@ -3266,10 +3250,10 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
else
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
}
else if (samplePosition >= sampleLength)
else if ((samplePosition < 0) || (samplePosition >= sampleLength))
{
interpolating = 0;
break;
@ -3283,7 +3267,6 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples)
if ( !resampler_ready(resampler) )
{
p->voice[ch].sampleData = NULL;
p->voice[ch].samplePosition = 0;
p->voice[ch].busy = 0;
break;
}
@ -3410,14 +3393,9 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition]);
if (loopDir == 1)
{
if (--samplePosition < 0)
samplePosition = 0;
}
--samplePosition;
else
{
++samplePosition;
}
if (loopEnabled)
{
@ -3427,7 +3405,7 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition <= sampleLoopBegin)
{
samplePosition += (sampleLoopBegin - samplePosition) - 1;
samplePosition = sampleLoopBegin + (sampleLoopBegin - samplePosition);
loopDir = 0;
}
}
@ -3435,7 +3413,7 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
{
if (samplePosition >= sampleLoopEnd)
{
samplePosition -= (samplePosition - sampleLoopEnd) + 1;
samplePosition = sampleLoopEnd - (samplePosition - sampleLoopEnd);
loopDir = 1;
}
}
@ -3443,10 +3421,10 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
else
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
}
else if (samplePosition >= sampleLength)
else if ((samplePosition < 0) || (samplePosition >= sampleLength))
{
interpolating = 0;
break;
@ -3460,7 +3438,6 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples)
if ( !resampler_ready(resampler[0]) )
{
p->voice[ch].sampleData = NULL;
p->voice[ch].samplePosition = 0;
p->voice[ch].busy = 0;
break;
}

View File

@ -2922,6 +2922,7 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples)
int32_t sampleLength;
int32_t sampleLoopEnd;
int32_t sampleLoopLength;
int32_t sampleLoopBegin;
int32_t samplePosition;
int32_t interpolating;
#ifdef USE_VOL_RAMP
@ -2941,6 +2942,7 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples)
sampleLength = p->voice[ch].sampleLength;
sampleLoopLength = p->voice[ch].sampleLoopLength;
sampleLoopEnd = p->voice[ch].sampleLoopEnd;
sampleLoopBegin = sampleLoopEnd - sampleLoopLength;
loopEnabled = p->voice[ch].loopEnabled;
volume = p->voice[ch].volume;
panningL = p->voice[ch].panningL;
@ -2961,20 +2963,17 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples)
{
resampler_write_sample(resampler, sampleData[samplePosition] * 256);
samplePosition++;
++samplePosition;
if (loopEnabled)
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
else
{
if (samplePosition >= sampleLength)
{
samplePosition = 0;
interpolating = 0;
}
}
}
@ -3057,6 +3056,7 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
int32_t sampleLength;
int32_t sampleLoopEnd;
int32_t sampleLoopLength;
int32_t sampleLoopBegin;
int32_t samplePosition;
int32_t interpolating;
#ifdef USE_VOL_RAMP
@ -3077,6 +3077,7 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
sampleLength = p->voice[ch].sampleLength;
sampleLoopLength = p->voice[ch].sampleLoopLength;
sampleLoopEnd = p->voice[ch].sampleLoopEnd;
sampleLoopBegin = sampleLoopEnd - sampleLoopLength;
loopEnabled = p->voice[ch].loopEnabled;
volume = p->voice[ch].volume;
panningL = p->voice[ch].panningL;
@ -3104,20 +3105,17 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
resampler_write_sample(resampler[0], sampleData[samplePosition] * 256);
resampler_write_sample(resampler[1], sampleData[sampleLength + samplePosition] * 256);
samplePosition++;
++samplePosition;
if (loopEnabled)
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
else
{
if (samplePosition >= sampleLength)
{
samplePosition = 0;
interpolating = 0;
}
}
}
@ -3203,6 +3201,7 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples)
int32_t sampleLength;
int32_t sampleLoopEnd;
int32_t sampleLoopLength;
int32_t sampleLoopBegin;
int32_t samplePosition;
int32_t interpolating;
#ifdef USE_VOL_RAMP
@ -3222,6 +3221,7 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples)
sampleLength = p->voice[ch].sampleLength;
sampleLoopLength = p->voice[ch].sampleLoopLength;
sampleLoopEnd = p->voice[ch].sampleLoopEnd;
sampleLoopBegin = sampleLoopEnd - sampleLoopLength;
loopEnabled = p->voice[ch].loopEnabled;
volume = p->voice[ch].volume;
panningL = p->voice[ch].panningL;
@ -3242,20 +3242,17 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples)
{
resampler_write_sample(resampler, get_le16(&sampleData[samplePosition]));
samplePosition++;
++samplePosition;
if (loopEnabled)
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
else
{
if (samplePosition >= sampleLength)
{
samplePosition = 0;
interpolating = 0;
}
}
}
@ -3338,6 +3335,7 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
int32_t sampleLength;
int32_t sampleLoopEnd;
int32_t sampleLoopLength;
int32_t sampleLoopBegin;
int32_t samplePosition;
int32_t interpolating;
#ifdef USE_VOL_RAMP
@ -3358,6 +3356,7 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
sampleLength = p->voice[ch].sampleLength;
sampleLoopLength = p->voice[ch].sampleLoopLength;
sampleLoopEnd = p->voice[ch].sampleLoopEnd;
sampleLoopBegin = sampleLoopEnd - sampleLoopLength;
loopEnabled = p->voice[ch].loopEnabled;
volume = p->voice[ch].volume;
panningL = p->voice[ch].panningL;
@ -3385,20 +3384,17 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples)
resampler_write_sample(resampler[0], get_le16(&sampleData[samplePosition]));
resampler_write_sample(resampler[1], get_le16(&sampleData[sampleLength + samplePosition]));
samplePosition++;
++samplePosition;
if (loopEnabled)
{
if (samplePosition >= sampleLoopEnd)
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
}
else
{
if (samplePosition >= sampleLength)
{
samplePosition = 0;
interpolating = 0;
}
}
}
@ -3492,6 +3488,7 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
int32_t sampleLength;
int32_t sampleLoopEnd;
int32_t sampleLoopLength;
int32_t sampleLoopBegin;
int32_t samplePosition;
#ifdef USE_VOL_RAMP
int32_t rampStyle;
@ -3512,6 +3509,7 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
sampleLength = p->voice[ch].sampleLength;
sampleLoopLength = p->voice[ch].sampleLoopLength;
sampleLoopEnd = p->voice[ch].sampleLoopEnd;
sampleLoopBegin = sampleLoopEnd - sampleLoopLength;
loopEnabled = p->voice[ch].loopEnabled;
volume = p->voice[ch].volume;
panningL = p->voice[ch].panningL;
@ -3547,7 +3545,7 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
lastDelta = nextDelta;
samplePosition++;
++samplePosition;
if (loopEnabled)
{
@ -3556,17 +3554,14 @@ static inline void mixadpcm(PLAYER *p, uint8_t ch, uint32_t samples)
if (samplePosition >= sampleLoopEnd)
{
samplePosition -= sampleLoopLength;
samplePosition = sampleLoopBegin + (samplePosition - sampleLoopEnd);
lastDelta = p->voice[ch].loopStartDelta;
}
}
else
{
if (samplePosition >= sampleLength)
{
samplePosition = 0;
interpolating = 0;
}
}
}
@ -3720,7 +3715,7 @@ static void st3play_AdlibMix(PLAYER *p, float *buffer, int32_t count)
if (inbuffer_free)
{
Chip_GenerateBlock2( p->fmChip, inbuffer_free, tempbuffer );
Chip_GenerateBlock_Mono( p->fmChip, inbuffer_free, tempbuffer );
for (i = 0; i < inbuffer_free; ++i)
resampler_write_sample_fixed( p->fmResampler, (int)tempbuffer[i], 16);
}