2008-05-06 05:35:37 +02:00
|
|
|
#include "coding.h"
|
2008-02-04 13:23:35 +01:00
|
|
|
#include "../util.h"
|
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
|
2008-02-05 01:03:39 +01:00
|
|
|
int i;
|
2008-02-04 13:23:35 +01:00
|
|
|
int32_t sample_count;
|
2017-05-13 22:17:27 +02:00
|
|
|
int32_t frame_samples = (frame_bytes - 2) * 2;
|
2008-02-04 13:23:35 +01:00
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
int framesin = first_sample/frame_samples;
|
2008-02-05 01:03:39 +01:00
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
int32_t scale = read_16bitBE(stream->offset+framesin*frame_bytes,stream->streamfile) + 1;
|
2008-02-04 13:23:35 +01:00
|
|
|
int32_t hist1 = stream->adpcm_history1_32;
|
|
|
|
int32_t hist2 = stream->adpcm_history2_32;
|
|
|
|
int coef1 = stream->adpcm_coef[0];
|
|
|
|
int coef2 = stream->adpcm_coef[1];
|
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
first_sample = first_sample%frame_samples;
|
2008-02-05 01:03:39 +01:00
|
|
|
|
2017-05-14 00:37:24 +02:00
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
int sample_byte = read_8bit(stream->offset+framesin*frame_bytes +2+i/2,stream->streamfile);
|
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(
|
|
|
|
(i&1?
|
|
|
|
get_low_nibble_signed(sample_byte):
|
|
|
|
get_high_nibble_signed(sample_byte)
|
|
|
|
) * scale +
|
2017-05-14 01:16:32 +02:00
|
|
|
(coef1 * hist1 >> 12) + (coef2 * hist2 >> 12)
|
2017-05-14 00:37:24 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
hist2 = hist1;
|
|
|
|
hist1 = outbuf[sample_count];
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->adpcm_history1_32 = hist1;
|
|
|
|
stream->adpcm_history2_32 = hist2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void decode_adx_exp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
int32_t frame_samples = (frame_bytes - 2) * 2;
|
|
|
|
|
|
|
|
int framesin = first_sample/frame_samples;
|
|
|
|
|
|
|
|
int32_t scale = read_16bitBE(stream->offset+framesin*frame_bytes,stream->streamfile);
|
|
|
|
scale = 1 << (12 - scale);
|
|
|
|
int32_t hist1 = stream->adpcm_history1_32;
|
|
|
|
int32_t hist2 = stream->adpcm_history2_32;
|
|
|
|
int coef1 = stream->adpcm_coef[0];
|
|
|
|
int coef2 = stream->adpcm_coef[1];
|
|
|
|
|
|
|
|
first_sample = first_sample%frame_samples;
|
|
|
|
|
2008-02-04 13:23:35 +01:00
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
2017-05-13 22:17:27 +02:00
|
|
|
int sample_byte = read_8bit(stream->offset+framesin*frame_bytes +2+i/2,stream->streamfile);
|
2017-05-13 23:04:30 +02:00
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(
|
|
|
|
(i&1?
|
|
|
|
get_low_nibble_signed(sample_byte):
|
|
|
|
get_high_nibble_signed(sample_byte)
|
|
|
|
) * scale +
|
2017-05-14 01:16:32 +02:00
|
|
|
(coef1 * hist1 >> 12) + (coef2 * hist2 >> 12)
|
2017-05-13 23:04:30 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
hist2 = hist1;
|
|
|
|
hist1 = outbuf[sample_count];
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->adpcm_history1_32 = hist1;
|
|
|
|
stream->adpcm_history2_32 = hist2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void decode_adx_fixed(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
int32_t frame_samples = (frame_bytes - 2) * 2;
|
|
|
|
|
|
|
|
int framesin = first_sample/frame_samples;
|
|
|
|
|
|
|
|
int32_t scale = (read_16bitBE(stream->offset + framesin*frame_bytes, stream->streamfile) & 0x1FFF) + 1;
|
|
|
|
int32_t predictor = read_8bit(stream->offset + framesin*frame_bytes, stream->streamfile) >> 5;
|
|
|
|
int32_t hist1 = stream->adpcm_history1_32;
|
|
|
|
int32_t hist2 = stream->adpcm_history2_32;
|
|
|
|
int coef1 = stream->adpcm_coef[predictor * 2];
|
|
|
|
int coef2 = stream->adpcm_coef[predictor * 2 + 1];
|
|
|
|
|
|
|
|
first_sample = first_sample%frame_samples;
|
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
int sample_byte = read_8bit(stream->offset+framesin*frame_bytes +2+i/2,stream->streamfile);
|
2008-02-04 13:23:35 +01:00
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(
|
|
|
|
(i&1?
|
|
|
|
get_low_nibble_signed(sample_byte):
|
|
|
|
get_high_nibble_signed(sample_byte)
|
|
|
|
) * scale +
|
2017-05-14 01:16:32 +02:00
|
|
|
(coef1 * hist1 >> 12) + (coef2 * hist2 >> 12)
|
2008-02-04 13:23:35 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
hist2 = hist1;
|
|
|
|
hist1 = outbuf[sample_count];
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->adpcm_history1_32 = hist1;
|
|
|
|
stream->adpcm_history2_32 = hist2;
|
|
|
|
}
|
2008-12-24 08:19:15 +01:00
|
|
|
|
|
|
|
void adx_next_key(VGMSTREAMCHANNEL * stream)
|
|
|
|
{
|
|
|
|
stream->adx_xor = ( stream->adx_xor * stream->adx_mult + stream->adx_add ) & 0x7fff;
|
|
|
|
}
|
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
|
2008-12-24 08:19:15 +01:00
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
2017-05-13 22:17:27 +02:00
|
|
|
int32_t frame_samples = (frame_bytes - 2) * 2;
|
2008-12-24 08:19:15 +01:00
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
int framesin = first_sample/frame_samples;
|
2008-12-24 08:19:15 +01:00
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
int32_t scale = ((read_16bitBE(stream->offset+framesin*frame_bytes,stream->streamfile) ^ stream->adx_xor)&0x1fff) + 1;
|
2008-12-24 08:19:15 +01:00
|
|
|
int32_t hist1 = stream->adpcm_history1_32;
|
|
|
|
int32_t hist2 = stream->adpcm_history2_32;
|
|
|
|
int coef1 = stream->adpcm_coef[0];
|
|
|
|
int coef2 = stream->adpcm_coef[1];
|
|
|
|
|
2017-05-13 22:17:27 +02:00
|
|
|
first_sample = first_sample%frame_samples;
|
2008-12-24 08:19:15 +01:00
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
2017-05-13 22:17:27 +02:00
|
|
|
int sample_byte = read_8bit(stream->offset+framesin*frame_bytes +2+i/2,stream->streamfile);
|
2008-12-24 08:19:15 +01:00
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(
|
|
|
|
(i&1?
|
|
|
|
get_low_nibble_signed(sample_byte):
|
|
|
|
get_high_nibble_signed(sample_byte)
|
|
|
|
) * scale +
|
2017-05-14 01:16:32 +02:00
|
|
|
(coef1 * hist1 >> 12) + (coef2 * hist2 >> 12)
|
2008-12-24 08:19:15 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
hist2 = hist1;
|
|
|
|
hist1 = outbuf[sample_count];
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->adpcm_history1_32 = hist1;
|
|
|
|
stream->adpcm_history2_32 = hist2;
|
|
|
|
|
|
|
|
if (!(i % 32)) {
|
|
|
|
for (i=0;i<stream->adx_channels;i++)
|
|
|
|
{
|
|
|
|
adx_next_key(stream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|