mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-24 23:10:10 +01:00
Validate some bytes-to-samples and shadowing tweaks
This commit is contained in:
parent
fd9a33d2d0
commit
c7a8e25ce8
@ -45,8 +45,8 @@ size_t xbox_ima_bytes_to_samples(size_t bytes, int channels);
|
||||
size_t apple_ima4_bytes_to_samples(size_t bytes, int channels);
|
||||
|
||||
/* ngc_dsp_decoder */
|
||||
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_ngc_dsp_subint(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave);
|
||||
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_ngc_dsp_subint(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave);
|
||||
size_t dsp_bytes_to_samples(size_t bytes, int channels);
|
||||
int32_t dsp_nibbles_to_samples(int32_t nibbles);
|
||||
void dsp_read_coefs_be(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing);
|
||||
@ -80,8 +80,8 @@ void decode_pcmfloat(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelsp
|
||||
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample);
|
||||
|
||||
/* psx_decoder */
|
||||
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags);
|
||||
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size);
|
||||
void decode_psx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags);
|
||||
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size);
|
||||
int ps_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t * out_loop_start, int32_t * out_loop_end);
|
||||
int ps_find_loop_offsets_full(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, size_t interleave, int32_t * out_loop_start, int32_t * out_loop_end);
|
||||
size_t ps_bytes_to_samples(size_t bytes, int channels);
|
||||
@ -123,9 +123,9 @@ void free_acm(acm_codec_data *data);
|
||||
void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do);
|
||||
|
||||
/* msadpcm_decoder */
|
||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
|
||||
|
||||
/* yamaha_decoder */
|
||||
@ -175,8 +175,8 @@ void decode_derf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
void decode_circus_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
/* oki_decoder */
|
||||
void decode_pcfx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode);
|
||||
void decode_oki16(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_pcfx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode);
|
||||
void decode_oki16(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
size_t oki_bytes_to_samples(size_t bytes, int channels);
|
||||
|
||||
/* ea_mt_decoder*/
|
||||
|
@ -1111,11 +1111,13 @@ void decode_h4m_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspa
|
||||
/* ************************************************************* */
|
||||
|
||||
size_t ima_bytes_to_samples(size_t bytes, int channels) {
|
||||
if (channels <= 0) return 0;
|
||||
/* 2 samples per byte (2 nibbles) in stereo or mono config */
|
||||
return bytes * 2 / channels;
|
||||
}
|
||||
|
||||
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) {
|
||||
if (block_align <= 0 || channels <= 0) return 0;
|
||||
/* MS-IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
|
||||
return (bytes / block_align) * ((block_align - 0x04*channels) * 2 / channels + 1)
|
||||
+ ((bytes % block_align) ? (((bytes % block_align) - 0x04*channels) * 2 / channels + 1) : 0);
|
||||
@ -1123,6 +1125,7 @@ size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) {
|
||||
|
||||
size_t xbox_ima_bytes_to_samples(size_t bytes, int channels) {
|
||||
int block_align = 0x24 * channels;
|
||||
if (channels <= 0) return 0;
|
||||
/* XBOX IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
|
||||
return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0); /* unlikely (encoder aligns) */
|
||||
@ -1130,6 +1133,7 @@ size_t xbox_ima_bytes_to_samples(size_t bytes, int channels) {
|
||||
|
||||
size_t apple_ima4_bytes_to_samples(size_t bytes, int channels) {
|
||||
int block_align = 0x22 * channels;
|
||||
if (channels <= 0) return 0;
|
||||
return (bytes / block_align) * (block_align - 0x02*channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 0x02*channels) * 2 / channels : 0);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ static const int msadpcm_coefs[7][2] = {
|
||||
{ 392, -232 }
|
||||
};
|
||||
|
||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do) {
|
||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL *ch1,*ch2;
|
||||
STREAMFILE *streamfile;
|
||||
int i, frames_in;
|
||||
@ -97,7 +97,7 @@ void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first
|
||||
}
|
||||
}
|
||||
|
||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
VGMSTREAMCHANNEL *stream = &vgmstream->ch[channel];
|
||||
int i, frames_in;
|
||||
size_t bytes_per_frame, samples_per_frame;
|
||||
@ -160,7 +160,7 @@ void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int channelspac
|
||||
|
||||
/* Cricket Audio's MSADPCM, same thing with reversed hist and nibble order
|
||||
* (their tools may convert to float/others but internally it's all PCM16, from debugging). */
|
||||
void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
VGMSTREAMCHANNEL *stream = &vgmstream->ch[channel];
|
||||
int i, frames_in;
|
||||
size_t bytes_per_frame, samples_per_frame;
|
||||
@ -222,6 +222,7 @@ void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample * outbuf, int channelspacin
|
||||
}
|
||||
|
||||
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
|
||||
if (block_size <= 0 || channels <= 0) return 0;
|
||||
return (bytes / block_size) * (block_size - (7-1)*channels) * 2 / channels
|
||||
+ ((bytes % block_size) ? ((bytes % block_size) - (7-1)*channels) * 2 / channels : 0);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i=first_sample;
|
||||
int32_t sample_count;
|
||||
|
||||
@ -37,7 +37,7 @@ void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
||||
}
|
||||
|
||||
/* read from memory rather than a file */
|
||||
static void decode_ngc_dsp_subint_internal(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, uint8_t * mem) {
|
||||
static void decode_ngc_dsp_subint_internal(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, uint8_t * mem) {
|
||||
int i=first_sample;
|
||||
int32_t sample_count;
|
||||
|
||||
@ -71,7 +71,7 @@ static void decode_ngc_dsp_subint_internal(VGMSTREAMCHANNEL * stream, sample * o
|
||||
}
|
||||
|
||||
/* decode DSP with byte-interleaved frames (ex. 0x08: 1122112211221122) */
|
||||
void decode_ngc_dsp_subint(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave) {
|
||||
void decode_ngc_dsp_subint(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int interleave) {
|
||||
uint8_t sample_data[0x08];
|
||||
int i;
|
||||
|
||||
@ -100,21 +100,12 @@ int32_t dsp_nibbles_to_samples(int32_t nibbles) {
|
||||
int32_t whole_frames = nibbles/16;
|
||||
int32_t remainder = nibbles%16;
|
||||
|
||||
/*
|
||||
fprintf(stderr,"%d (%#x) nibbles => %x bytes and %d samples\n",nibbles,nibbles,whole_frames*8,remainder);
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (remainder > 0 && remainder < 14)
|
||||
return whole_frames*14 + remainder;
|
||||
else if (remainder >= 14)
|
||||
fprintf(stderr,"***** last frame %d leftover nibbles makes no sense\n",remainder);
|
||||
#endif
|
||||
if (remainder>0) return whole_frames*14+remainder-2;
|
||||
else return whole_frames*14;
|
||||
}
|
||||
|
||||
size_t dsp_bytes_to_samples(size_t bytes, int channels) {
|
||||
if (channels <= 0) return 0;
|
||||
return bytes / channels / 8 * 14;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ static void oki16_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, in
|
||||
* so it's needs GENH/TXTH. Sample rate can only be base_value divided by 1/2/3/4, where
|
||||
* base_value is approximately ~31468.5 (follows hardware clocks), mono or interleaved for stereo.
|
||||
*/
|
||||
void decode_pcfx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode) {
|
||||
void decode_pcfx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int mode) {
|
||||
int i, sample_count = 0;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int step_index = stream->adpcm_step_index;
|
||||
@ -108,7 +108,7 @@ void decode_pcfx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
|
||||
/* OKI variation with 16-bit output (vs standard's 12-bit), found in FrontWing's PS2 games (Sweet Legacy, Hooligan).
|
||||
* Reverse engineered from the ELF with help from the folks at hcs. */
|
||||
void decode_oki16(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
void decode_oki16(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, sample_count = 0;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int step_index = stream->adpcm_step_index;
|
||||
@ -140,6 +140,7 @@ void decode_oki16(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing
|
||||
|
||||
|
||||
size_t oki_bytes_to_samples(size_t bytes, int channels) {
|
||||
if (channels <= 0) return 0;
|
||||
/* 2 samples per byte (2 nibbles) in stereo or mono config */
|
||||
return bytes * 2 / channels;
|
||||
}
|
||||
|
@ -221,5 +221,6 @@ void decode_pcmfloat(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelsp
|
||||
}
|
||||
|
||||
size_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample) {
|
||||
if (channels <= 0 || bits_per_sample <= 0) return 0;
|
||||
return ((int64_t)bytes * 8) / channels / bits_per_sample;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ static const int ps_adpcm_coefs_i[5][2] = {
|
||||
*/
|
||||
|
||||
/* standard PS-ADPCM (float math version) */
|
||||
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags) {
|
||||
void decode_psx(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags) {
|
||||
off_t frame_offset;
|
||||
int i, frames_in, sample_count = 0;
|
||||
size_t bytes_per_frame, samples_per_frame;
|
||||
@ -75,24 +75,24 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t new_sample = 0;
|
||||
int32_t sample = 0;
|
||||
|
||||
if (flag < 0x07) { /* with flag 0x07 decoded sample must be 0 */
|
||||
uint8_t nibbles = (uint8_t)read_8bit(frame_offset+0x02+i/2,stream->streamfile);
|
||||
|
||||
new_sample = i&1 ? /* low nibble first */
|
||||
sample = i&1 ? /* low nibble first */
|
||||
(nibbles >> 4) & 0x0f :
|
||||
(nibbles >> 0) & 0x0f;
|
||||
new_sample = (int16_t)((new_sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
new_sample = (int)(new_sample + ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2);
|
||||
new_sample = clamp16(new_sample);
|
||||
sample = (int16_t)((sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
sample = (int)(sample + ps_adpcm_coefs_f[coef_index][0]*hist1 + ps_adpcm_coefs_f[coef_index][1]*hist2);
|
||||
sample = clamp16(sample);
|
||||
}
|
||||
|
||||
outbuf[sample_count] = new_sample;
|
||||
outbuf[sample_count] = sample;
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = new_sample;
|
||||
hist1 = sample;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
@ -104,7 +104,7 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
* Found in some PC/PS3 games (FF XI in sizes 3/5/9/41, Afrika in size 4, Blur/James Bond in size 33, etc).
|
||||
*
|
||||
* Uses int math to decode, which seems more likely (based on FF XI PC's code in Moogle Toolbox). */
|
||||
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size) {
|
||||
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size) {
|
||||
off_t frame_offset;
|
||||
int i, frames_in, sample_count = 0;
|
||||
size_t bytes_per_frame, samples_per_frame;
|
||||
@ -131,21 +131,21 @@ void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int cha
|
||||
|
||||
/* decode nibbles */
|
||||
for (i = first_sample; i < first_sample + samples_to_do; i++) {
|
||||
int32_t new_sample = 0;
|
||||
int32_t sample = 0;
|
||||
uint8_t nibbles = (uint8_t)read_8bit(frame_offset+0x01+i/2,stream->streamfile);
|
||||
|
||||
new_sample = i&1 ? /* low nibble first */
|
||||
sample = i&1 ? /* low nibble first */
|
||||
(nibbles >> 4) & 0x0f :
|
||||
(nibbles >> 0) & 0x0f;
|
||||
new_sample = (int16_t)((new_sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
new_sample = new_sample + ((ps_adpcm_coefs_i[coef_index][0]*hist1 + ps_adpcm_coefs_i[coef_index][1]*hist2) >> 6);
|
||||
new_sample = clamp16(new_sample);
|
||||
sample = (int16_t)((sample << 12) & 0xf000) >> shift_factor; /* 16b sign extend + scale */
|
||||
sample = sample + ((ps_adpcm_coefs_i[coef_index][0]*hist1 + ps_adpcm_coefs_i[coef_index][1]*hist2) >> 6);
|
||||
sample = clamp16(sample);
|
||||
|
||||
outbuf[sample_count] = new_sample;
|
||||
outbuf[sample_count] = sample;
|
||||
sample_count += channelspacing;
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = new_sample;
|
||||
hist1 = sample;
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
@ -269,6 +269,7 @@ int ps_find_loop_offsets_full(STREAMFILE *streamFile, off_t start_offset, size_t
|
||||
}
|
||||
|
||||
size_t ps_bytes_to_samples(size_t bytes, int channels) {
|
||||
if (channels <= 0) return 0;
|
||||
return bytes / channels / 0x10 * 28;
|
||||
}
|
||||
|
||||
|
@ -151,13 +151,14 @@ void decode_nxap(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacin
|
||||
}
|
||||
|
||||
size_t yamaha_bytes_to_samples(size_t bytes, int channels) {
|
||||
if (channels <= 0) return 0;
|
||||
/* 2 samples per byte (2 nibbles) in stereo or mono config */
|
||||
return bytes * 2 / channels;
|
||||
}
|
||||
|
||||
size_t aska_bytes_to_samples(size_t bytes, int channels) {
|
||||
int block_align = 0x40;
|
||||
|
||||
if (channels <= 0) return 0;
|
||||
return (bytes / block_align) * (block_align - 0x04*channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 0x04*channels) * 2 / channels : 0);
|
||||
}
|
||||
|
@ -1146,12 +1146,8 @@ fail:
|
||||
}
|
||||
|
||||
static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
|
||||
if (!txth->channels)
|
||||
return 0; /* div-by-zero is no fun */
|
||||
|
||||
switch(txth->codec) {
|
||||
case MS_IMA:
|
||||
if (!txth->interleave) return 0;
|
||||
return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels);
|
||||
case XBOX:
|
||||
return xbox_ima_bytes_to_samples(bytes, txth->channels);
|
||||
@ -1171,7 +1167,6 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
|
||||
case PCM4_U:
|
||||
return pcm_bytes_to_samples(bytes, txth->channels, 4);
|
||||
case MSADPCM:
|
||||
if (!txth->interleave) return 0;
|
||||
return msadpcm_bytes_to_samples(bytes, txth->interleave, txth->channels);
|
||||
case ATRAC3:
|
||||
return atrac3_bytes_to_samples(bytes, txth->interleave);
|
||||
|
Loading…
Reference in New Issue
Block a user