Made DUMB and modplay volume ramping more sensitive when transititioning to or from zero volume, and implemented Modplug ADPCM sample support into ft2play

CQTexperiment
Chris Moeller 2014-03-28 17:53:08 -07:00
parent 4504bf1034
commit 7a0aea53dd
3 changed files with 68 additions and 9 deletions

View File

@ -3905,6 +3905,13 @@ static void playing_volume_setup(DUMB_IT_SIGRENDERER * sigrenderer, IT_PLAYING *
vol = calculate_volume(sigrenderer, playing, 1.0f);
playing->float_volume[0] *= vol;
playing->float_volume[1] *= vol;
rampScale = 4;
if (ramp_style > 0 && playing->declick_stage == 2) {
if ((playing->ramp_volume[0] == 0 && playing->ramp_volume[1] == 0) || vol == 0)
rampScale = 48;
}
if (ramp_style == 0 || (ramp_style < 2 && playing->declick_stage == 2)) {
if (playing->declick_stage <= 2) {
@ -3921,7 +3928,6 @@ static void playing_volume_setup(DUMB_IT_SIGRENDERER * sigrenderer, IT_PLAYING *
playing->ramp_delta[0] = 0;
playing->ramp_delta[1] = 0;
} else {
rampScale = 4;
if (playing->declick_stage == 0) {
playing->ramp_volume[0] = 0;
playing->ramp_volume[1] = 0;

View File

@ -81,6 +81,7 @@ typedef struct SampleHeaderTyp_t
uint8_t Typ;
uint8_t Pan;
int8_t RelTon;
uint8_t Junk;
}
#ifdef __GNUC__
__attribute__ ((packed))
@ -171,6 +172,7 @@ typedef struct SampleTyp_t
uint8_t Typ;
uint8_t Pan;
int8_t RelTon;
uint8_t Junk;
int8_t *Pek;
} SampleTyp;
@ -2251,7 +2253,7 @@ static int8_t LoadInstrHeader(PLAYER *p, MEM *buf, uint16_t i)
}
if ((ih.SampleSize == 0) || (ih.SampleSize > 40)) ih.SampleSize = 40; // default
ih.SampleSize -= (1 + 22); // skip junk + name
ih.SampleSize -= (22); // skip name
if (ih.AntSamp > 32) return (0);
@ -2264,9 +2266,9 @@ static int8_t LoadInstrHeader(PLAYER *p, MEM *buf, uint16_t i)
for (j = 0; j < ih.AntSamp; ++j)
{
mread(&ih.Samp[j], 17, 1, buf);
mseek(buf, 1 + 22, SEEK_CUR); // skip junk + name
memcpy(&p->Instr[i]->Samp[j], &ih.Samp[j], 17);
mread(&ih.Samp[j], 18, 1, buf);
mseek(buf, 22, SEEK_CUR); // skip junk + name
memcpy(&p->Instr[i]->Samp[j], &ih.Samp[j], 18);
// non-FT2 fix: Force loop flags off if loop length is 0
if (p->Instr[i]->Samp[j].RepL == 0)
@ -2292,6 +2294,40 @@ static void CheckSampleRepeat(PLAYER *p, uint16_t ins, uint8_t smp)
}
}
static inline int8_t get_adpcm_sample(const int8_t *sampleDictionary, const uint8_t *sampleData, int32_t samplePosition, int8_t *lastDelta)
{
uint8_t byte = sampleData[samplePosition / 2];
byte = (samplePosition & 1) ? byte >> 4 : byte & 15;
return *lastDelta += sampleDictionary[byte];
}
static void Adpcm2Samp(uint8_t * sample, uint32_t length)
{
const int8_t *sampleDictionary;
const uint8_t *sampleData;
uint32_t samplePosition;
int8_t lastDelta;
uint8_t * sampleDataOut = (uint8_t *) malloc(length);
if (!sampleDataOut)
return;
sampleDictionary = (const int8_t *)sample;
sampleData = (uint8_t*)sampleDictionary + 16;
samplePosition = 0;
lastDelta = 0;
while (samplePosition < length)
{
sampleDataOut[samplePosition] = get_adpcm_sample(sampleDictionary, sampleData, samplePosition, &lastDelta);
samplePosition++;
}
memcpy(sample, sampleDataOut, length);
}
static int8_t LoadInstrSample(PLAYER *p, MEM *buf, uint16_t i)
{
uint16_t j;
@ -2301,9 +2337,13 @@ static int8_t LoadInstrSample(PLAYER *p, MEM *buf, uint16_t i)
{
for (j = 1; j <= p->Instr[i]->AntSamp; ++j)
{
int adpcm = 0;
p->Instr[i]->Samp[j - 1].Pek = NULL;
l = p->Instr[i]->Samp[j - 1].Len;
if (p->Instr[i]->Samp[j - 1].Junk == 0xAD &&
!(p->Instr[i]->Samp[j - 1].Typ & (16|32)))
adpcm = (((l + 1) / 2) + 16);
if (l > 0)
{
p->Instr[i]->Samp[j - 1].Pek = (int8_t *)(malloc(l));
@ -2313,8 +2353,11 @@ static int8_t LoadInstrSample(PLAYER *p, MEM *buf, uint16_t i)
return (0);
}
mread(p->Instr[i]->Samp[j - 1].Pek, l, 1, buf);
Delta2Samp(p->Instr[i]->Samp[j - 1].Pek, l, p->Instr[i]->Samp[j - 1].Typ);
mread(p->Instr[i]->Samp[j - 1].Pek, adpcm ? adpcm : l, 1, buf);
if (!adpcm)
Delta2Samp(p->Instr[i]->Samp[j - 1].Pek, l, p->Instr[i]->Samp[j - 1].Typ);
else
Adpcm2Samp(p->Instr[i]->Samp[j - 1].Pek, l);
}
CheckSampleRepeat(p, i, (uint8_t)(j) - 1);
@ -2721,6 +2764,11 @@ void voiceSetSamplePosition(PLAYER *p, uint8_t i, uint16_t value)
void voiceSetVolume(PLAYER *p, uint8_t i, float vol, uint8_t pan, uint8_t sharp)
{
#ifdef USE_VOL_RAMP
if (p->rampStyle > 0 && !sharp)
{
if ((p->voice[i].volumeL == 0 && p->voice[i].volumeR == 0) || vol == 0)
sharp = 3;
}
if (p->rampStyle > 1 || (p->rampStyle > 0 && sharp))
{
const float rampRate = sharp ? p->f_samplesPerFrameSharp : p->f_samplesPerFrame;
@ -2731,7 +2779,7 @@ void voiceSetVolume(PLAYER *p, uint8_t i, float vol, uint8_t pan, uint8_t sharp)
p->voice[i].volumeL = 0.0f;
p->voice[i].volumeR = 0.0f;
}
else
else if (sharp != 3)
p->voice[i].rampTerminates = 1;
}

View File

@ -2683,6 +2683,11 @@ void voiceSetSamplePosition(PLAYER *p, uint8_t voiceNumber, uint16_t value)
void voiceSetVolume(PLAYER *p, uint8_t voiceNumber, float volume, uint8_t sharp)
{
#ifdef USE_VOL_RAMP
if (p->rampStyle > 0 && !sharp)
{
if (p->voice[voiceNumber].volume == 0 || volume == 0)
sharp = 3;
}
if (p->rampStyle > 1 || (p->rampStyle > 0 && sharp != 0))
{
const float rampRate = sharp ? p->f_samplesPerFrameSharp : p->f_samplesPerFrame;
@ -2690,7 +2695,7 @@ void voiceSetVolume(PLAYER *p, uint8_t voiceNumber, float volume, uint8_t sharp)
{
if (volume)
p->voice[voiceNumber].volume = 0.0f;
else
else if (sharp != 3)
p->voice[voiceNumber].rampTerminates = 1;
}
p->voice[voiceNumber].targetVol = volume;