summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vincent-Halver <Vincent.Halver@gmail.com>2025-07-26 04:58:32 -0700
committer GitHub <noreply@github.com>2025-07-26 07:58:32 -0400
commit063a9615b09fe8437412f717d6aa34d317faa53d (patch)
treed61f02420cf280ea75dca990b7f426c11081d7c2
parent7b183bf6335906442e877b4d1f3d845431545cd3 (diff)
CD-i: Fixes XA audio header offset (#13993)
* Simplify cdicdic.cpp This simplifies the reference functions while making small changes to the used functions. * Simplify cdicdic Reduced by 37 lines. * CD-i: Fixes XA audio header offset Fixes Github #13991
-rw-r--r--src/mame/philips/cdicdic.cpp186
-rw-r--r--src/mame/philips/cdicdic.h9
2 files changed, 49 insertions, 146 deletions
diff --git a/src/mame/philips/cdicdic.cpp b/src/mame/philips/cdicdic.cpp
index 136607bce60..8be63d6a756 100644
--- a/src/mame/philips/cdicdic.cpp
+++ b/src/mame/philips/cdicdic.cpp
@@ -256,248 +256,150 @@ const uint8_t cdicdic_device::s_sector_scramble[2448] =
// MEMBER FUNCTIONS
//**************************************************************************
-void cdicdic_device::decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
+int16_t clip_int16(int32_t sample) {
+ if (sample < -32768)
+ return -32768;
+ else if (sample > 32767)
+ return 32767;
+ return sample;
+}
+
+inline void rotate_samples(int16_t val, int16_t& a, int16_t& b, int16_t& output) {
+ b = a;
+ a = val;
+ output = a;
+}
+void cdicdic_device::decode_xa_unit(const uint8_t param, int16_t sample, int16_t& sample0, int16_t& sample1, int16_t& out_buffer)
{
- int16_t l0 = cdic_xa_last[0];
- int16_t l1 = cdic_xa_last[1];
+ const int16_t* filter = s_xa_filter_coef[(param >> 4) & 3];
+ uint8_t range = (param & 0xf);
+ sample = (sample>>range) + ((filter[0] * sample0 + filter[1] * sample1 + 128) >> 8);
+
+ //int16_t sample16 = clip_int16(sample);
+ rotate_samples(sample, sample0, sample1, out_buffer);
+}
+void cdicdic_device::decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
+{
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags = xa[4 + (s << 1)];
- uint8_t shift = flags & 0xf;
- uint8_t filter = (flags >> 4) & 3;
- int16_t f0 = s_xa_filter_coef[filter][0];
- int16_t f1 = s_xa_filter_coef[filter][1];
for (int32_t i = 0; i < 28; i++)
{
+ //int16_t sample = ((*data) & 0xf) << 12;
int16_t d = (xa[16 + (i << 2) + s] & 0xf) << 12;
- d = (d >> shift) + (((l0 * f0) + (l1 * f1) + 128) >> 8);
- *dp = d;
+ decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
- l1 = l0;
- l0 = d;
}
flags = xa[5 + (s << 1)];
- shift = flags & 0xf;
- filter = flags >> 4;
- f0 = s_xa_filter_coef[filter][0];
- f1 = s_xa_filter_coef[filter][1];
for (int32_t i = 0; i < 28; i++)
{
+ //int16_t sample = (*data >> 4) << 12;
int16_t d = (xa[16 + (i << 2) + s] >> 4) << 12;
- d = (d >> shift) + (((l0 * f0) + (l1 * f1) + 128) >> 8);
- *dp = d;
+ decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
- l1 = l0;
- l0 = d;
}
}
xa += 128;
}
-
- cdic_xa_last[0] = l0;
- cdic_xa_last[1] = l1;
}
-void cdicdic_device::decode_xa_mono8(int16_t *cdic_xa_last, const unsigned char *xa, signed short *dp)
+void cdicdic_device::decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t*dp)
{
- int16_t l0 = cdic_xa_last[0];
- int16_t l1 = cdic_xa_last[1];
-
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags = xa[4 + s];
- uint8_t shift = flags & 0xf;
- uint8_t filter = (flags >> 4) & 3;
- int16_t f0 = s_xa_filter_coef[filter][0];
- int16_t f1 = s_xa_filter_coef[filter][1];
-
for (int32_t i = 0; i < 28; i++)
{
int16_t d = (xa[16 + (i << 2) + s] << 8);
- d = (d >> shift) + (((l0 * f0) + (l1 * f1) + 128) >> 8);
- *dp = d;
+ decode_xa_unit(flags, d, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
- l1 = l0;
- l0 = d;
}
}
xa += 128;
}
-
- cdic_xa_last[0] = l0;
- cdic_xa_last[1] = l1;
}
void cdicdic_device::decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
{
- int16_t l0 = cdic_xa_last[0];
- int16_t l1 = cdic_xa_last[1];
- int16_t l2 = cdic_xa_last[2];
- int16_t l3 = cdic_xa_last[3];
-
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s++)
{
uint8_t flags0 = xa[4 + (s << 1)];
- uint8_t shift0 = flags0 & 0xf;
- uint8_t filter0 = (flags0 >> 4) & 3;
uint8_t flags1 = xa[5 + (s << 1)];
- uint8_t shift1 = flags1 & 0xf;
- uint8_t filter1 = (flags1 >> 4) & 3;
-
- int16_t f0 = s_xa_filter_coef[filter0][0];
- int16_t f1 = s_xa_filter_coef[filter0][1];
- int16_t f2 = s_xa_filter_coef[filter1][0];
- int16_t f3 = s_xa_filter_coef[filter1][1];
for (int32_t i = 0; i < 28; i++)
{
int16_t d = xa[16 + (i << 2) + s];
int16_t d0 = (d & 0xf) << 12;
- int16_t d1 = (d >> 4) << 12;
- d0 = (d0 >> shift0) + (((l0 * f0) + (l1 * f1) + 128) >> 8);
- *dp = d0;
+ decode_xa_unit(flags0, d0, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
- l1 = l0;
- l0 = d0;
- d1 = (d1 >> shift1) + (((l2 * f2) + (l3 * f3) + 128) >> 8);
- *dp = d1;
+ int16_t d1 = (d >> 4) << 12;
+ decode_xa_unit(flags1, d1, cdic_xa_last[2], cdic_xa_last[3], dp[0]);
dp++;
- l3 = l2;
- l2 = d1;
}
}
xa += 128;
}
-
- cdic_xa_last[0] = l0;
- cdic_xa_last[1] = l1;
- cdic_xa_last[2] = l2;
- cdic_xa_last[3] = l3;
}
void cdicdic_device::decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp)
{
- int16_t l0 = cdic_xa_last[0];
- int16_t l1 = cdic_xa_last[1];
- int16_t l2 = cdic_xa_last[2];
- int16_t l3 = cdic_xa_last[3];
-
for (int32_t b = 0; b < 18; b++)
{
for (int32_t s = 0; s < 4; s += 2)
{
uint8_t flags0 = xa[4 + s];
- uint8_t shift0 = flags0 & 0xf;
- uint8_t filter0 = (flags0 >> 4) & 3;
uint8_t flags1 = xa[5 + s];
- uint8_t shift1 = flags1 & 0xf;
- uint8_t filter1 = (flags1 >> 4) & 3;
- int16_t f0 = s_xa_filter_coef[filter0][0];
- int16_t f1 = s_xa_filter_coef[filter0][1];
- int16_t f2 = s_xa_filter_coef[filter1][0];
- int16_t f3 = s_xa_filter_coef[filter1][1];
for (int32_t i = 0; i < 28; i++)
{
int16_t d0 = (xa[16 + (i << 2) + s + 0] << 8);
- int16_t d1 = (xa[16 + (i << 2) + s + 1] << 8);
- d0 = (d0 >> shift0) + (((l0 * f0) + (l1 * f1) + 128) >> 8);
- *dp = d0;
+ decode_xa_unit(flags0, d0, cdic_xa_last[0], cdic_xa_last[1], dp[0]);
dp++;
- l1 = l0;
- l0 = d0;
- d1 = (d1 >> shift1) + (((l2 * f2) + (l3 * f3) + 128) >> 8);
- *dp = d1;
+ int16_t d1 = (xa[16 + (i << 2) + s + 1] << 8);
+ decode_xa_unit(flags1, d1, cdic_xa_last[2], cdic_xa_last[3], dp[0]);
dp++;
- l3 = l2;
- l2 = d1;
}
}
-
xa += 128;
}
-
- cdic_xa_last[0] = l0;
- cdic_xa_last[1] = l1;
- cdic_xa_last[2] = l2;
- cdic_xa_last[3] = l3;
}
+
void cdicdic_device::decode_8bit_xa_unit(int channel, uint8_t param, const uint8_t *data, int16_t *out_buffer)
{
- int gain_shift = 8 - (param & 0xf);
-
- const int16_t *filter = s_xa_filter_coef[(param >> 4) & 3];
- int16_t *old_samples = &m_xa_last[channel << 1];
-
+ int16_t* old_samples = &m_xa_last[channel << 1];
for (int i = 0; i < 28; i++)
{
- int32_t sample = *data;
- if (sample >= 128)
- sample -= 256;
+ int16_t sample = (*data)<<8;
+ decode_xa_unit(param, sample, old_samples[0], old_samples[1], out_buffer[i]);
data += 4;
-
- sample <<= gain_shift;
-
- sample += (filter[0] * old_samples[0] + filter[1] * old_samples[1] + 128) / 256;
-
- int16_t sample16 = (int16_t)sample;
- if (sample < -32768)
- sample16 = -32768;
- else if (sample > 32767)
- sample16 = 32767;
-
- old_samples[1] = old_samples[0];
- old_samples[0] = sample16;
-
- out_buffer[i] = sample16;
}
}
void cdicdic_device::decode_4bit_xa_unit(int channel, uint8_t param, const uint8_t *data, uint8_t shift, int16_t *out_buffer)
{
- int gain_shift = 12 - (param & 0xf);
-
- const int16_t *filter = s_xa_filter_coef[(param >> 4) & 3];
- int16_t *old_samples = &m_xa_last[channel << 1];
-
+ int16_t* old_samples = &m_xa_last[channel << 1];
for (int i = 0; i < 28; i++)
{
- int32_t sample = (*data >> shift) & 0xf;
- if (BIT(sample, 3))
- sample -= 16;
+ int16_t sample = ((*data >> shift) & 0xf)<<12;
+ decode_xa_unit(param, sample, old_samples[0], old_samples[1], out_buffer[i]);
data += 4;
-
- sample <<= gain_shift;
-
- sample += (filter[0] * old_samples[0] + filter[1] * old_samples[1] + 128) / 256;
-
- int16_t sample16 = (int16_t)(uint16_t)(sample & 0xffff);
- if (sample < -32768)
- sample16 = -32768;
- else if (sample > 32767)
- sample16 = 32767;
-
- old_samples[1] = old_samples[0];
- old_samples[0] = sample16;
-
- out_buffer[i] = sample16;
}
}
@@ -516,8 +418,8 @@ void cdicdic_device::play_raw_group(const uint8_t *data)
void cdicdic_device::play_xa_group(const uint8_t coding, const uint8_t *data)
{
- static const uint16_t s_4bit_header_offsets[8] = { 0, 1, 2, 3, 8, 9, 10, 11 };
- static const uint16_t s_8bit_header_offsets[4] = { 0, 1, 2, 3 };
+ static const uint16_t s_4bit_header_offsets[8] = { 4, 5, 6, 7, 12, 13, 14, 15 };
+ static const uint16_t s_8bit_header_offsets[4] = { 4, 5, 6, 7 };
static const uint16_t s_4bit_data_offsets[8] = { 16, 16, 17, 17, 18, 18, 19, 19 };
static const uint16_t s_8bit_data_offsets[4] = { 16, 17, 18, 19 };
diff --git a/src/mame/philips/cdicdic.h b/src/mame/philips/cdicdic.h
index cc253fc7091..b725ae4f299 100644
--- a/src/mame/philips/cdicdic.h
+++ b/src/mame/philips/cdicdic.h
@@ -190,6 +190,7 @@ private:
std::unique_ptr<uint8_t[]> m_ram;
std::unique_ptr<int16_t[]> m_samples[2];
+ void decode_xa_unit(const uint8_t param, int16_t sample, int16_t& sample0, int16_t& sample1, int16_t& out_buffer);
void decode_8bit_xa_unit(int channel, uint8_t param, const uint8_t *data, int16_t *out_buffer);
void decode_4bit_xa_unit(int channel, uint8_t param, const uint8_t *data, uint8_t shift, int16_t *out_buffer);
void play_raw_group(const uint8_t *data);
@@ -214,10 +215,10 @@ private:
uint32_t lba_from_time();
static uint8_t get_sector_count_for_coding(uint8_t coding);
- static void decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
- static void decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
- static void decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
- static void decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
+ void decode_xa_mono(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
+ void decode_xa_mono8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
+ void decode_xa_stereo(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
+ void decode_xa_stereo8(int16_t *cdic_xa_last, const uint8_t *xa, int16_t *dp);
static const int16_t s_xa_filter_coef[4][2];
static const int32_t s_samples_per_sector;