phase actually has 18 fractional bits, not 10

This commit is contained in:
Anthony Pesch 2017-07-25 17:23:45 -04:00
parent 2e1524a259
commit ff3aa7c551
1 changed files with 60 additions and 55 deletions

View File

@ -34,14 +34,18 @@ DEFINE_AGGREGATE_COUNTER(aica_samples);
#define AICA_REG_LO(addr, mask) (((addr)&0x3) == 0)
#define AICA_REG_HI(addr, mask) ((((addr)&0x3) != 0) || ((mask) != 0xff))
/* phase increment has 10 fractional bits */
#define AICA_PHASE_FRC_BITS 10
#define AICA_BASE_FREQ (1 << AICA_PHASE_FRC_BITS)
/* phase increment has 18 fractional bits */
#define AICA_PHASE_FRAC_BITS 18
#define AICA_PHASE_BASE (1 << AICA_PHASE_FRAC_BITS)
/* ADPCM decoding constants */
#define ADPCM_QUANT_MIN 0x7f
#define ADPCM_QUANT_MAX 0x6000
/* work with samples as 64-bit ints to avoid dealing with overflow issues
during intermediate steps */
typedef int64_t sample_t;
/* amplitude / frequency envelope generator state */
struct aica_eg_state {
int state;
@ -61,21 +65,20 @@ struct aica_channel {
/* base address in host memory of sound data */
uint8_t *base;
/* how much to step the sound source each sample */
uint32_t phaseinc;
/* current position in the sound source */
int phase;
/* fractional remainder after phase increment */
uint32_t phasefrc;
int phasefrc;
/* amount to step the sound source each sample */
int phaseinc;
int pos;
/* previous sample state */
sample_t prev_sample;
sample_t prev_quant;
/* signals the the current channel has looped */
int looped;
/* previous sample state */
int32_t prev_sample;
int32_t prev_quant;
/*struct aica_eg_state aeg;
struct aica_eg_state feg;*/
};
@ -110,8 +113,8 @@ struct aica {
};
/* approximated lookup tables for MVOL / TL scaling */
static int32_t mvol_scale[16];
static int32_t tl_scale[256];
static sample_t mvol_scale[16];
static sample_t tl_scale[256];
static char *aica_fmt_names[] = {
"PCMS16", /* AICA_FMT_PCMS16 */
@ -160,7 +163,7 @@ static void aica_init_tables() {
}
/* a 32-bit int is used for the scale, leaving 15 bits for the fraction */
mvol_scale[i] = (int32_t)((1 << 15) / pow(2.0f, (15 - i) / 2.0f));
mvol_scale[i] = (sample_t)((1 << 15) / pow(2.0f, (15 - i) / 2.0f));
}
/* each channel's TL register adjusts the output level based on the table:
@ -181,25 +184,25 @@ static void aica_init_tables() {
for (int i = 0; i < 256; i++) {
/* a 32-bit int is used for the scale, leaving 15 bits for the fraction */
tl_scale[i] = (int32_t)((1 << 15) / pow(2.0f, i / 16.0f));
tl_scale[i] = (sample_t)((1 << 15) / pow(2.0f, i / 16.0f));
}
}
static inline int32_t aica_adjust_master_volume(struct aica *aica, int32_t in) {
int32_t y = mvol_scale[aica->common_data->MVOL];
static inline sample_t aica_adjust_master_volume(struct aica *aica, sample_t in) {
sample_t y = mvol_scale[aica->common_data->MVOL];
/* truncate fraction */
return (in * y) >> 15;
}
static inline int32_t aica_adjust_channel_volume(struct aica_channel *ch,
int32_t in) {
int32_t y = tl_scale[ch->data->TL];
static inline sample_t aica_adjust_channel_volume(struct aica_channel *ch,
sample_t in) {
sample_t y = tl_scale[ch->data->TL];
/* truncate fraction */
return (in * y) >> 15;
}
static void aica_decode_adpcm(int32_t data, int32_t prev, int32_t prev_quant,
int32_t *next, int32_t *next_quant) {
static void aica_decode_adpcm(sample_t data, sample_t prev, sample_t prev_quant,
sample_t *next, sample_t *next_quant) {
/* the decoded value (n) = (1 - 2 * l4) * (l3 + l2/2 + l1/4 + 1/8) * quantized
width (n) + decoded value (n - 1)
@ -217,7 +220,7 @@ static void aica_decode_adpcm(int32_t data, int32_t prev, int32_t prev_quant,
1 1 1 15
the final value is a signed 16-bit value and must be clamped as such */
static int32_t adpcm_scale[8] = {1, 3, 5, 7, 9, 11, 13, 15};
static sample_t adpcm_scale[8] = {1, 3, 5, 7, 9, 11, 13, 15};
int l4 = data >> 3;
int l321 = data & 0x7;
@ -242,7 +245,7 @@ static void aica_decode_adpcm(int32_t data, int32_t prev, int32_t prev_quant,
1 1 1 2.3984375 (614 / 256)
the quantized width's min value is 127, and its max value is 24576 */
static int32_t adpcm_rate[8] = {230, 230, 230, 230, 307, 409, 512, 614};
static sample_t adpcm_rate[8] = {230, 230, 230, 230, 307, 409, 512, 614};
*next_quant = (prev_quant * adpcm_rate[l321]) >> 8;
*next_quant = CLAMP(*next_quant, ADPCM_QUANT_MIN, ADPCM_QUANT_MAX);
@ -426,7 +429,7 @@ static void aica_rtc_timer(void *data) {
}
static float aica_channel_hz(struct aica_channel *ch) {
return (AICA_SAMPLE_FREQ * ch->phaseinc) / (float)AICA_BASE_FREQ;
return (AICA_SAMPLE_FREQ * ch->phaseinc) / (float)AICA_PHASE_BASE;
}
static float aica_channel_duration(struct aica_channel *ch) {
@ -434,16 +437,18 @@ static float aica_channel_duration(struct aica_channel *ch) {
return ch->data->LEA / hz;
}
static uint32_t aica_channel_phaseinc(struct aica_channel *ch) {
/* by default, step a single sample at a time */
uint32_t phaseinc = AICA_BASE_FREQ;
static int aica_channel_phaseinc(struct aica_channel *ch) {
/* by default, increment by one sample per step */
int phaseinc = AICA_PHASE_BASE;
/* FNS represents the fractional phase increment, used to linearly
interpolate between samples */
phaseinc |= ch->data->FNS;
/* FNS represents the fractional phase increment, used to linearly interpolate
between samples. note, the phase increment has 18 total fractional bits,
but FNS is only 10 bits enabling lowest octave (which causes a right shift
by 8) to still have 10 bits for interpolation */
phaseinc |= ch->data->FNS << 8;
/* OCT represents a full octave pitch shift in two's complement, ranging
from -8 to +7 */
/* OCT represents a full octave pitch shift in two's complement, ranging from
-8 to +7 */
uint32_t oct = ch->data->OCT;
if (oct & 0x8) {
phaseinc >>= (16 - oct);
@ -480,9 +485,9 @@ static void aica_channel_key_on(struct aica *aica, struct aica_channel *ch) {
ch->active = 1;
ch->base = aica_channel_base(aica, ch);
ch->phaseinc = aica_channel_phaseinc(ch);
ch->phase = 0;
ch->phasefrc = 0;
ch->pos = 0;
ch->phaseinc = aica_channel_phaseinc(ch);
ch->looped = 0;
ch->prev_sample = 0;
ch->prev_quant = ADPCM_QUANT_MIN;
@ -513,7 +518,7 @@ static void aica_channel_key_on_execute(struct aica *aica,
ch->data->KYONEX = 0;
}
static int32_t aica_channel_step(struct aica *aica, struct aica_channel *ch) {
static sample_t aica_channel_step(struct aica *aica, struct aica_channel *ch) {
if (!ch->active) {
return 0;
}
@ -522,29 +527,29 @@ static int32_t aica_channel_step(struct aica *aica, struct aica_channel *ch) {
/* the data returned is a signed 16-bit PCM data, but signed 32-bit values are
used intermediately to avoid dealing with overflows until the end */
int32_t next_sample = 0;
int32_t next_quant = 0;
sample_t next_sample = 0;
sample_t next_quant = 0;
/* step the stream */
ch->phasefrc += ch->phaseinc;
while (ch->phasefrc >= AICA_BASE_FREQ) {
while (ch->phasefrc >= AICA_PHASE_BASE) {
if (ch->data->SSCTL) {
LOG_WARNING("SSCTL input not supported");
} else {
switch (ch->data->PCMS) {
case AICA_FMT_PCMS16: {
next_sample = *(int16_t *)&ch->base[ch->pos << 1];
next_sample = *(int16_t *)&ch->base[ch->phase << 1];
} break;
case AICA_FMT_PCMS8: {
next_sample = *(int8_t *)&ch->base[ch->pos] << 8;
next_sample = *(int8_t *)&ch->base[ch->phase] << 8;
} break;
case AICA_FMT_ADPCM:
case AICA_FMT_ADPCM_STREAM: {
int shift = (ch->pos & 1) << 2;
int32_t data = (ch->base[ch->pos >> 1] >> shift) & 0xf;
int shift = (ch->phase & 1) << 2;
sample_t data = (ch->base[ch->phase >> 1] >> shift) & 0xf;
aica_decode_adpcm(data, ch->prev_sample, ch->prev_quant, &next_sample,
&next_quant);
} break;
@ -557,23 +562,23 @@ static int32_t aica_channel_step(struct aica *aica, struct aica_channel *ch) {
ch->prev_sample = next_sample;
ch->prev_quant = next_quant;
ch->phasefrc -= AICA_BASE_FREQ;
ch->pos++;
ch->phasefrc -= AICA_PHASE_BASE;
ch->phase++;
}
/* interpolate sample */
int32_t result = ch->prev_sample * (AICA_BASE_FREQ - ch->phasefrc);
sample_t result = ch->prev_sample * (AICA_PHASE_BASE - ch->phasefrc);
result += next_sample * ch->phasefrc;
result >>= AICA_PHASE_FRC_BITS;
result >>= AICA_PHASE_FRAC_BITS;
/* shift to DECAY1 once starting the loop */
if (ch->data->LPSLNK && ch->pos >= ch->data->LSA) {
if (ch->data->LPSLNK && ch->phase >= ch->data->LSA) {
LOG_WARNING("EG not currently supported");
}
/* check if the current position in the sound source has passed the loop end
position */
if (ch->pos >= ch->data->LEA) {
if (ch->phase >= ch->data->LEA) {
ch->looped = 1;
LOG_AICA("aica_channel_step [%d] looped", ch->id);
@ -585,7 +590,7 @@ static int32_t aica_channel_step(struct aica *aica, struct aica_channel *ch) {
case AICA_LOOP_FORWARD: {
/* restart channel at loop start address */
ch->pos = ch->data->LSA;
ch->phase = ch->data->LSA;
/* in ADPCM streaming mode, the loop is a ring buffer. don't reset the
decoding state in this case */
@ -605,12 +610,12 @@ static void aica_generate_frames(struct aica *aica) {
int16_t buffer[AICA_BATCH_SIZE * 2];
for (int frame = 0; frame < AICA_BATCH_SIZE; frame++) {
int32_t l = 0;
int32_t r = 0;
sample_t l = 0;
sample_t r = 0;
for (int i = 0; i < AICA_NUM_CHANNELS; i++) {
struct aica_channel *ch = &aica->channels[i];
int32_t s = aica_channel_step(aica, ch);
sample_t s = aica_channel_step(aica, ch);
l += aica_adjust_channel_volume(ch, s);
r += aica_adjust_channel_volume(ch, s);
}
@ -705,7 +710,7 @@ static uint32_t aica_common_reg_read(struct aica *aica, uint32_t addr,
case 0x14: { /* CA */
struct aica_channel *ch = &aica->channels[aica->common_data->MSLC];
aica->common_data->CA = ch->pos;
aica->common_data->CA = ch->phase;
} break;
case 0x90: { /* TIMA, TACTL */