mirror of
https://github.com/AxioDL/amuse.git
synced 2025-12-09 13:37:47 +00:00
MusyX 1 compatibility fixes, Rogue Squadron N64 decoding confirmed
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "amuse/N64MusyXCodec.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Acknowledgements:
|
||||
* SubDrag for N64 Sound Tool (http://www.goldeneyevault.com/viewfile.php?id=212)
|
||||
@@ -72,68 +73,44 @@ static unsigned adpcm_decode_upto_8_samples(int16_t* dst, const int16_t* src,
|
||||
return size;
|
||||
}
|
||||
|
||||
static unsigned adpcm_decode_upto_8_samples_ranged(int16_t* dst, const int16_t* src,
|
||||
const int16_t* cb_entry,
|
||||
const int16_t* last_samples,
|
||||
unsigned firstSample,
|
||||
unsigned size)
|
||||
{
|
||||
if (firstSample >= size)
|
||||
return 0;
|
||||
|
||||
const int16_t* book1 = cb_entry;
|
||||
const int16_t* book2 = cb_entry + 8;
|
||||
|
||||
int16_t l1 = last_samples[0];
|
||||
int16_t l2 = last_samples[1];
|
||||
|
||||
int accu;
|
||||
|
||||
unsigned ret = 0;
|
||||
for (unsigned i=firstSample ; i<size ; ++i)
|
||||
{
|
||||
accu = (int)src[i] << 11;
|
||||
accu += book1[i] * l1 + book2[i] * l2 + rdot(i, book2, src);
|
||||
*dst++ = N64MusyXSampClamp(accu >> 11);
|
||||
++ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned N64MusyXDecompressFrame(int16_t* out, const uint8_t* in,
|
||||
const int16_t coefs[8][2][8],
|
||||
unsigned lastSample)
|
||||
{
|
||||
int16_t frame[32];
|
||||
|
||||
unsigned remSamples = lastSample;
|
||||
unsigned samples = 0;
|
||||
unsigned procSamples;
|
||||
unsigned procSamples, procRes;
|
||||
|
||||
unsigned char c2 = in[0x8];
|
||||
c2 = c2 % 0x80;
|
||||
|
||||
const int16_t* bookPredictors = coefs[(c2 & 0xf0) >> 8][0];
|
||||
const int16_t* bookPredictors = coefs[(c2 & 0xf0) >> 4][0];
|
||||
unsigned int rshift = (c2 & 0x0f);
|
||||
|
||||
adpcm_get_predicted_frame(frame, &in[0x0], &in[0x8], rshift);
|
||||
|
||||
procSamples = (lastSample < 2) ? lastSample : 2;
|
||||
procSamples = (remSamples < 2) ? remSamples : 2;
|
||||
memcpy(out, frame, 2 * procSamples);
|
||||
samples += procSamples;
|
||||
remSamples -= procSamples;
|
||||
if (samples == lastSample)
|
||||
return samples;
|
||||
|
||||
#define adpcm_decode_upto_end_samples(inOffset, bookPredictors, outOffset, size) \
|
||||
procSamples = (lastSample < size) ? lastSample : size; \
|
||||
samples += adpcm_decode_upto_8_samples(out + inOffset, frame + inOffset, bookPredictors, out + outOffset, procSamples); \
|
||||
#define adpcm_decode_upto_end_samples(inOffset, outOffset, size) \
|
||||
procSamples = (remSamples < size) ? remSamples : size; \
|
||||
procRes = adpcm_decode_upto_8_samples(out + inOffset, frame + inOffset, bookPredictors, \
|
||||
out + outOffset, procSamples); \
|
||||
samples += procRes; \
|
||||
remSamples -= procRes; \
|
||||
if (samples == lastSample) \
|
||||
return samples;
|
||||
|
||||
adpcm_decode_upto_end_samples(2, bookPredictors, 0, 6);
|
||||
adpcm_decode_upto_end_samples(8, bookPredictors, 6, 8);
|
||||
adpcm_decode_upto_end_samples(16, bookPredictors, 14, 8);
|
||||
adpcm_decode_upto_end_samples(24, bookPredictors, 22, 8);
|
||||
adpcm_decode_upto_end_samples(2, 0, 6);
|
||||
adpcm_decode_upto_end_samples(8, 6, 8);
|
||||
adpcm_decode_upto_end_samples(16, 14, 8);
|
||||
adpcm_decode_upto_end_samples(24, 22, 8);
|
||||
|
||||
out += 32;
|
||||
|
||||
@@ -141,21 +118,22 @@ unsigned N64MusyXDecompressFrame(int16_t* out, const uint8_t* in,
|
||||
c2 = in[0x18];
|
||||
c2 = c2 % 0x80;
|
||||
|
||||
bookPredictors = coefs[(c2 & 0xf0) >> 8][0];
|
||||
bookPredictors = coefs[(c2 & 0xf0) >> 4][0];
|
||||
rshift = (c2 & 0x0f);
|
||||
|
||||
adpcm_get_predicted_frame(frame, &in[0x4], &in[0x18], rshift);
|
||||
|
||||
procSamples = (lastSample < 2) ? lastSample : 2;
|
||||
procSamples = (remSamples < 2) ? remSamples : 2;
|
||||
memcpy(out, frame, 2 * procSamples);
|
||||
samples += procSamples;
|
||||
remSamples -= procSamples;
|
||||
if (samples == lastSample)
|
||||
return samples;
|
||||
|
||||
adpcm_decode_upto_end_samples(2, bookPredictors, 0, 6);
|
||||
adpcm_decode_upto_end_samples(8, bookPredictors, 6, 8);
|
||||
adpcm_decode_upto_end_samples(16, bookPredictors, 14, 8);
|
||||
adpcm_decode_upto_end_samples(24, bookPredictors, 22, 8);
|
||||
adpcm_decode_upto_end_samples(2, 0, 6);
|
||||
adpcm_decode_upto_end_samples(8, 6, 8);
|
||||
adpcm_decode_upto_end_samples(16, 14, 8);
|
||||
adpcm_decode_upto_end_samples(24, 22, 8);
|
||||
|
||||
return samples;
|
||||
}
|
||||
@@ -164,61 +142,10 @@ unsigned N64MusyXDecompressFrameRanged(int16_t* out, const uint8_t* in,
|
||||
const int16_t coefs[8][2][8],
|
||||
unsigned firstSample, unsigned lastSample)
|
||||
{
|
||||
int16_t frame[32];
|
||||
|
||||
unsigned samples = 0;
|
||||
unsigned procSamples;
|
||||
|
||||
unsigned char c2 = in[0x8];
|
||||
c2 = c2 % 0x80;
|
||||
|
||||
const int16_t* bookPredictors = coefs[(c2 & 0xf0) >> 8][0];
|
||||
unsigned int rshift = (c2 & 0x0f);
|
||||
|
||||
adpcm_get_predicted_frame(frame, &in[0x0], &in[0x8], rshift);
|
||||
|
||||
procSamples = (lastSample < 2) ? lastSample : 2;
|
||||
memcpy(out, frame, 2 * procSamples);
|
||||
samples += procSamples;
|
||||
firstSample = (2 > firstSample) ? 0 : (firstSample - 2);
|
||||
if (samples == lastSample)
|
||||
return samples;
|
||||
|
||||
#define adpcm_decode_upto_end_samples_ranged(inOffset, bookPredictors, outOffset, size) \
|
||||
procSamples = (lastSample < size) ? lastSample : size; \
|
||||
samples += adpcm_decode_upto_8_samples_ranged(out + inOffset, frame + inOffset, bookPredictors, out + outOffset, firstSample, procSamples); \
|
||||
firstSample = (size > firstSample) ? 0 : (firstSample - size); \
|
||||
if (samples == lastSample) \
|
||||
return samples;\
|
||||
|
||||
adpcm_decode_upto_end_samples_ranged(2, bookPredictors, 0, 6);
|
||||
adpcm_decode_upto_end_samples_ranged(8, bookPredictors, 6, 8);
|
||||
adpcm_decode_upto_end_samples_ranged(16, bookPredictors, 14, 8);
|
||||
adpcm_decode_upto_end_samples_ranged(24, bookPredictors, 22, 8);
|
||||
|
||||
out += 32;
|
||||
|
||||
|
||||
c2 = in[0x18];
|
||||
c2 = c2 % 0x80;
|
||||
|
||||
bookPredictors = coefs[(c2 & 0xf0) >> 8][0];
|
||||
rshift = (c2 & 0x0f);
|
||||
|
||||
adpcm_get_predicted_frame(frame, &in[0x4], &in[0x18], rshift);
|
||||
|
||||
procSamples = (lastSample < 2) ? lastSample : 2;
|
||||
memcpy(out, frame, 2 * procSamples);
|
||||
samples += procSamples;
|
||||
firstSample = (2 > firstSample) ? 0 : (firstSample - 2);
|
||||
if (samples == lastSample)
|
||||
return samples;
|
||||
|
||||
adpcm_decode_upto_end_samples_ranged(2, bookPredictors, 0, 6);
|
||||
adpcm_decode_upto_end_samples_ranged(8, bookPredictors, 6, 8);
|
||||
adpcm_decode_upto_end_samples_ranged(16, bookPredictors, 14, 8);
|
||||
adpcm_decode_upto_end_samples_ranged(24, bookPredictors, 22, 8);
|
||||
|
||||
int16_t final[64];
|
||||
unsigned procSamples = N64MusyXDecompressFrame(final, in, coefs, firstSample + lastSample);
|
||||
unsigned samples = procSamples - firstSample;
|
||||
memcpy(out, final + firstSample, samples * 2);
|
||||
return samples;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user