From 3264ce9154d8aaf0c891ae79f7bd6b94ec2e2813 Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Tue, 1 Apr 2014 14:12:54 -0700 Subject: [PATCH] Updated modplay --- Frameworks/modplay/modplay/dbopl.c | 36 +++++++++-- Frameworks/modplay/modplay/dbopl.h | 4 +- Frameworks/modplay/modplay/ft2play.c | 91 +++++++++++----------------- Frameworks/modplay/modplay/st3play.c | 47 +++++++------- 4 files changed, 88 insertions(+), 90 deletions(-) diff --git a/Frameworks/modplay/modplay/dbopl.c b/Frameworks/modplay/modplay/dbopl.c index aacee35f5..2dd909344 100644 --- a/Frameworks/modplay/modplay/dbopl.c +++ b/Frameworks/modplay/modplay/dbopl.c @@ -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; diff --git a/Frameworks/modplay/modplay/dbopl.h b/Frameworks/modplay/modplay/dbopl.h index f3268d5cf..c710eca8f 100644 --- a/Frameworks/modplay/modplay/dbopl.h +++ b/Frameworks/modplay/modplay/dbopl.h @@ -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 ); diff --git a/Frameworks/modplay/modplay/ft2play.c b/Frameworks/modplay/modplay/ft2play.c index 3000383ca..fea7d83a2 100644 --- a/Frameworks/modplay/modplay/ft2play.c +++ b/Frameworks/modplay/modplay/ft2play.c @@ -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; } diff --git a/Frameworks/modplay/modplay/st3play.c b/Frameworks/modplay/modplay/st3play.c index 8d80884f8..5d2f09530 100644 --- a/Frameworks/modplay/modplay/st3play.c +++ b/Frameworks/modplay/modplay/st3play.c @@ -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); }