mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-12 09:03:10 +01:00
cleanup: fix rare leaks and misc tweaks
This commit is contained in:
parent
7b8ea3319a
commit
7d838f55d0
@ -890,10 +890,13 @@ static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
|||||||
//setvbuf(outfile, NULL, _IOFBF, SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
//setvbuf(outfile, NULL, _IOFBF, SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
||||||
//setvbuf(outfile, NULL, _IONBF, 0);
|
//setvbuf(outfile, NULL, _IONBF, 0);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// decode only: outfile is NULL (won't write anything)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decode forever */
|
/* decode forever */
|
||||||
while (cfg->play_forever) {
|
while (cfg->play_forever && !cfg->decode_only) {
|
||||||
int to_get = SAMPLE_BUFFER_SIZE;
|
int to_get = SAMPLE_BUFFER_SIZE;
|
||||||
|
|
||||||
render_vgmstream(buf, to_get, vgmstream);
|
render_vgmstream(buf, to_get, vgmstream);
|
||||||
@ -931,12 +934,12 @@ static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outfile && !cfg->play_sdtout)
|
if (outfile && outfile != stdout)
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
free(buf);
|
free(buf);
|
||||||
return 1;
|
return 1;
|
||||||
fail:
|
fail:
|
||||||
if (outfile && !cfg->play_sdtout)
|
if (outfile && outfile != stdout)
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -73,19 +73,23 @@ void decode_g7221(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, in
|
|||||||
|
|
||||||
|
|
||||||
void reset_g7221(g7221_codec_data* data) {
|
void reset_g7221(g7221_codec_data* data) {
|
||||||
int i;
|
if (!data)
|
||||||
if (!data) return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < data->channels; i++) {
|
for (int i = 0; i < data->channels; i++) {
|
||||||
|
if (!data->ch)
|
||||||
|
continue;
|
||||||
g7221_reset(data->ch[i].handle);
|
g7221_reset(data->ch[i].handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_g7221(g7221_codec_data* data) {
|
void free_g7221(g7221_codec_data* data) {
|
||||||
int i;
|
if (!data)
|
||||||
if (!data) return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < data->channels; i++) {
|
for (int i = 0; i < data->channels; i++) {
|
||||||
|
if (!data->ch)
|
||||||
|
continue;
|
||||||
g7221_free(data->ch[i].handle);
|
g7221_free(data->ch[i].handle);
|
||||||
}
|
}
|
||||||
free(data->ch);
|
free(data->ch);
|
||||||
@ -93,10 +97,12 @@ void free_g7221(g7221_codec_data* data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_key_g7221(g7221_codec_data* data, const uint8_t* key) {
|
void set_key_g7221(g7221_codec_data* data, const uint8_t* key) {
|
||||||
int i;
|
if (!data)
|
||||||
if (!data) return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < data->channels; i++) {
|
for (int i = 0; i < data->channels; i++) {
|
||||||
|
if (!data->ch)
|
||||||
|
continue;
|
||||||
g7221_set_key(data->ch[i].handle, key);
|
g7221_set_key(data->ch[i].handle, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,18 @@
|
|||||||
* - expand type: IMA style or variations; low or high nibble first
|
* - expand type: IMA style or variations; low or high nibble first
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const int ADPCMTable[90] = {
|
//TODO: decide on a better name and location
|
||||||
|
static inline int _clamp_s32(int value, int min, int max) {
|
||||||
|
if (value < min)
|
||||||
|
return min;
|
||||||
|
else if (value > max)
|
||||||
|
return max;
|
||||||
|
else
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const int16_t ima_step_size_table[89+1] = {
|
||||||
7, 8, 9, 10, 11, 12, 13, 14,
|
7, 8, 9, 10, 11, 12, 13, 14,
|
||||||
16, 17, 19, 21, 23, 25, 28, 31,
|
16, 17, 19, 21, 23, 25, 28, 31,
|
||||||
34, 37, 41, 45, 50, 55, 60, 66,
|
34, 37, 41, 45, 50, 55, 60, 66,
|
||||||
@ -28,7 +39,7 @@ static const int ADPCMTable[90] = {
|
|||||||
0 /* garbage value for Ubisoft IMA (see blocked_ubi_sce.c) */
|
0 /* garbage value for Ubisoft IMA (see blocked_ubi_sce.c) */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int IMA_IndexTable[16] = {
|
static const int8_t ima_index_table[16] = {
|
||||||
-1, -1, -1, -1, 2, 4, 6, 8,
|
-1, -1, -1, -1, 2, 4, 6, 8,
|
||||||
-1, -1, -1, -1, 2, 4, 6, 8
|
-1, -1, -1, -1, 2, 4, 6, 8
|
||||||
};
|
};
|
||||||
@ -46,7 +57,7 @@ static void std_ima_expand_nibble_data(uint8_t byte, int shift, int32_t* hist1,
|
|||||||
|
|
||||||
code = (byte >> shift) & 0xf;
|
code = (byte >> shift) & 0xf;
|
||||||
sample = *hist1; /* predictor value */
|
sample = *hist1; /* predictor value */
|
||||||
step = ADPCMTable[*index]; /* current step */
|
step = ima_step_size_table[*index]; /* current step */
|
||||||
|
|
||||||
delta = step >> 3;
|
delta = step >> 3;
|
||||||
if (code & 1) delta += step >> 2;
|
if (code & 1) delta += step >> 2;
|
||||||
@ -56,7 +67,7 @@ static void std_ima_expand_nibble_data(uint8_t byte, int shift, int32_t* hist1,
|
|||||||
sample += delta;
|
sample += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample);
|
*hist1 = clamp16(sample);
|
||||||
*index += IMA_IndexTable[code];
|
*index += ima_index_table[code];
|
||||||
if (*index < 0) *index = 0;
|
if (*index < 0) *index = 0;
|
||||||
if (*index > 88) *index = 88;
|
if (*index > 88) *index = 88;
|
||||||
}
|
}
|
||||||
@ -72,7 +83,7 @@ static void std_ima_expand_nibble_16(VGMSTREAMCHANNEL * stream, off_t byte_offse
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = step >> 3;
|
delta = step >> 3;
|
||||||
if (sample_nibble & 1) delta += step >> 2;
|
if (sample_nibble & 1) delta += step >> 2;
|
||||||
@ -82,7 +93,7 @@ static void std_ima_expand_nibble_16(VGMSTREAMCHANNEL * stream, off_t byte_offse
|
|||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded); /* no need for this, actually */
|
*hist1 = clamp16(sample_decoded); /* no need for this, actually */
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -100,7 +111,7 @@ static void std_ima_expand_nibble_mul(VGMSTREAMCHANNEL * stream, off_t byte_offs
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = (sample_nibble & 0x7);
|
delta = (sample_nibble & 0x7);
|
||||||
delta = ((delta * 2 + 1) * step) >> 3;
|
delta = ((delta * 2 + 1) * step) >> 3;
|
||||||
@ -108,7 +119,7 @@ static void std_ima_expand_nibble_mul(VGMSTREAMCHANNEL * stream, off_t byte_offs
|
|||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -119,7 +130,7 @@ static void nw_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
sample_decoded = sample_decoded << 3;
|
sample_decoded = sample_decoded << 3;
|
||||||
delta = (sample_nibble & 0x07);
|
delta = (sample_nibble & 0x07);
|
||||||
@ -129,7 +140,7 @@ static void nw_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
|||||||
sample_decoded = sample_decoded >> 3;
|
sample_decoded = sample_decoded >> 3;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -141,11 +152,11 @@ static void snds_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
|
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
|
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = (sample_nibble & 7) * step / 4 + step / 8; /* standard IMA */
|
delta = (sample_nibble & 7) * step / 4 + step / 8; /* standard IMA */
|
||||||
if (sample_nibble & 8) delta = -delta;
|
if (sample_nibble & 8) delta = -delta;
|
||||||
@ -160,7 +171,7 @@ static void otns_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = 0;
|
delta = 0;
|
||||||
if(sample_nibble & 4) delta = step * 4;
|
if(sample_nibble & 4) delta = step * 4;
|
||||||
@ -171,7 +182,7 @@ static void otns_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -182,7 +193,7 @@ static void wv6_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = (sample_nibble & 0x7);
|
delta = (sample_nibble & 0x7);
|
||||||
delta = ((delta * step) >> 3) + ((delta * step) >> 2);
|
delta = ((delta * step) >> 3) + ((delta * step) >> 2);
|
||||||
@ -190,7 +201,7 @@ static void wv6_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -201,7 +212,7 @@ static void hv_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = (sample_nibble & 0x7);
|
delta = (sample_nibble & 0x7);
|
||||||
delta = (delta * step) >> 2;
|
delta = (delta * step) >> 2;
|
||||||
@ -209,7 +220,7 @@ static void hv_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
|||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample_decoded);
|
*hist1 = clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -220,7 +231,7 @@ static void ffta2_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf; /* ADPCM code */
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf; /* ADPCM code */
|
||||||
sample_decoded = *hist1; /* predictor value */
|
sample_decoded = *hist1; /* predictor value */
|
||||||
step = ADPCMTable[*step_index] * 0x100; /* current step (table in ROM is pre-multiplied though) */
|
step = ima_step_size_table[*step_index] * 0x100; /* current step (table in ROM is pre-multiplied though) */
|
||||||
|
|
||||||
delta = step >> 3;
|
delta = step >> 3;
|
||||||
if (sample_nibble & 1) delta += step >> 2;
|
if (sample_nibble & 1) delta += step >> 2;
|
||||||
@ -238,7 +249,7 @@ static void ffta2_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
|
|||||||
*hist1 = sample_decoded;
|
*hist1 = sample_decoded;
|
||||||
*out_sample = (short)((sample_decoded + 128) / 256); /* int16 sample rounding, hist is kept as int32 */
|
*out_sample = (short)((sample_decoded + 128) / 256); /* int16 sample rounding, hist is kept as int32 */
|
||||||
|
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -249,7 +260,7 @@ static void blitz_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf; /* ADPCM code */
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf; /* ADPCM code */
|
||||||
sample_decoded = *hist1; /* predictor value */
|
sample_decoded = *hist1; /* predictor value */
|
||||||
step = ADPCMTable[*step_index]; /* current step */
|
step = ima_step_size_table[*step_index]; /* current step */
|
||||||
|
|
||||||
/* table has 2 different values, not enough to bother adding the full table */
|
/* table has 2 different values, not enough to bother adding the full table */
|
||||||
if (step == 22385)
|
if (step == 22385)
|
||||||
@ -265,7 +276,7 @@ static void blitz_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
|
|||||||
/* in Zapper somehow the exe tries to clamp hist but actually doesn't (bug? not in Lilo & Stitch),
|
/* in Zapper somehow the exe tries to clamp hist but actually doesn't (bug? not in Lilo & Stitch),
|
||||||
* seems the pcm buffer must be clamped outside though to fix some scratchiness */
|
* seems the pcm buffer must be clamped outside though to fix some scratchiness */
|
||||||
*hist1 = sample_decoded;//clamp16(sample_decoded);
|
*hist1 = sample_decoded;//clamp16(sample_decoded);
|
||||||
*step_index += IMA_IndexTable[sample_nibble];
|
*step_index += ima_index_table[sample_nibble];
|
||||||
if (*step_index < 0) *step_index=0;
|
if (*step_index < 0) *step_index=0;
|
||||||
if (*step_index > 88) *step_index=88;
|
if (*step_index > 88) *step_index=88;
|
||||||
}
|
}
|
||||||
@ -279,7 +290,7 @@ static void mtf_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset,
|
|||||||
|
|
||||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf;
|
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf;
|
||||||
sample_decoded = *hist1;
|
sample_decoded = *hist1;
|
||||||
step = ADPCMTable[*step_index];
|
step = ima_step_size_table[*step_index];
|
||||||
|
|
||||||
delta = step * (2 * sample_nibble - 15);
|
delta = step * (2 * sample_nibble - 15);
|
||||||
sample_decoded += delta;
|
sample_decoded += delta;
|
||||||
@ -339,7 +350,7 @@ static void cd_ima_expand_nibble(uint8_t byte, int shift, int32_t* hist1, int32_
|
|||||||
sample += delta;
|
sample += delta;
|
||||||
|
|
||||||
*hist1 = clamp16(sample);
|
*hist1 = clamp16(sample);
|
||||||
*index += IMA_IndexTable[code];
|
*index += ima_index_table[code];
|
||||||
if (*index < 0) *index=0;
|
if (*index < 0) *index=0;
|
||||||
if (*index > 88) *index=88;
|
if (*index > 88) *index=88;
|
||||||
}
|
}
|
||||||
@ -826,8 +837,7 @@ void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelsp
|
|||||||
|
|
||||||
hist1 = read_16bitLE(header_offset,stream->streamfile);
|
hist1 = read_16bitLE(header_offset,stream->streamfile);
|
||||||
step_index = read_8bit(header_offset+2,stream->streamfile);
|
step_index = read_8bit(header_offset+2,stream->streamfile);
|
||||||
|
step_index = _clamp_s32(step_index, 0, 88); /* probably pre-adjusted */
|
||||||
//todo clip step_index?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
@ -1237,15 +1247,6 @@ void decode_h4m_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspa
|
|||||||
stream->adpcm_step_index = step_index;
|
stream->adpcm_step_index = step_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test... */
|
|
||||||
static inline int _clamp_s32(int value, int min, int max) {
|
|
||||||
if (value < min)
|
|
||||||
return min;
|
|
||||||
else if (value > max)
|
|
||||||
return max;
|
|
||||||
else
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Crystal Dynamics IMA. Original code uses mind-bending intrinsics, so this may not be fully accurate.
|
/* Crystal Dynamics IMA. Original code uses mind-bending intrinsics, so this may not be fully accurate.
|
||||||
* Has another table with delta_table MMX combos, and uses header sample (first nibble is always 0). */
|
* Has another table with delta_table MMX combos, and uses header sample (first nibble is always 0). */
|
||||||
|
@ -212,63 +212,63 @@ static void bitreader_init(clData* br, const void *data, int size) {
|
|||||||
|
|
||||||
/* CRI's bitreader only handles 16b max during decode (header just reads bytes)
|
/* CRI's bitreader only handles 16b max during decode (header just reads bytes)
|
||||||
* so maybe could be optimized by ignoring higher cases */
|
* so maybe could be optimized by ignoring higher cases */
|
||||||
static unsigned int bitreader_peek(clData* br, int bitsize) {
|
static unsigned int bitreader_peek(clData* br, int bits_read) {
|
||||||
const unsigned int bit = br->bit;
|
const unsigned int bit_pos = br->bit;
|
||||||
const unsigned int bit_rem = bit & 7;
|
const unsigned int bit_rem = bit_pos & 7;
|
||||||
const unsigned int size = br->size;
|
const unsigned int bit_size = br->size;
|
||||||
unsigned int v = 0;
|
unsigned int v = 0;
|
||||||
unsigned int bit_offset, bit_left;
|
unsigned int bit_offset, bits_left;
|
||||||
|
|
||||||
if (bit + bitsize > size)
|
if (bit_pos + bits_read > bit_size)
|
||||||
return v;
|
return v;
|
||||||
if (bitsize == 0) /* may happen when resolution is 0 (dequantize_coefficients) */
|
if (bits_read == 0) /* may happen when resolution is 0 (dequantize_coefficients) */
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
bit_offset = bitsize + bit_rem;
|
bit_offset = bits_read + bit_rem;
|
||||||
bit_left = size - bit;
|
bits_left = bit_size - bit_pos;
|
||||||
if (bit_left >= 32 && bit_offset >= 25) {
|
if (bits_left >= 32 && bit_offset >= 25) {
|
||||||
static const unsigned int mask[8] = {
|
static const unsigned int mask[8] = {
|
||||||
0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF,
|
0xFFFFFFFF,0x7FFFFFFF,0x3FFFFFFF,0x1FFFFFFF,
|
||||||
0x0FFFFFFF,0x07FFFFFF,0x03FFFFFF,0x01FFFFFF
|
0x0FFFFFFF,0x07FFFFFF,0x03FFFFFF,0x01FFFFFF
|
||||||
};
|
};
|
||||||
const unsigned char* data = &br->data[bit >> 3];
|
const unsigned char* data = &br->data[bit_pos >> 3];
|
||||||
v = data[0];
|
v = data[0];
|
||||||
v = (v << 8) | data[1];
|
v = (v << 8) | data[1];
|
||||||
v = (v << 8) | data[2];
|
v = (v << 8) | data[2];
|
||||||
v = (v << 8) | data[3];
|
v = (v << 8) | data[3];
|
||||||
v &= mask[bit_rem];
|
v &= mask[bit_rem];
|
||||||
v >>= 32 - bit_rem - bitsize;
|
v >>= 32 - bit_rem - bits_read;
|
||||||
}
|
}
|
||||||
else if (bit_left >= 24 && bit_offset >= 17) {
|
else if (bits_left >= 24 && bit_offset >= 17) {
|
||||||
static const unsigned int mask[8] = {
|
static const unsigned int mask[8] = {
|
||||||
0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,
|
0xFFFFFF,0x7FFFFF,0x3FFFFF,0x1FFFFF,
|
||||||
0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF
|
0x0FFFFF,0x07FFFF,0x03FFFF,0x01FFFF
|
||||||
};
|
};
|
||||||
const unsigned char* data = &br->data[bit >> 3];
|
const unsigned char* data = &br->data[bit_pos >> 3];
|
||||||
v = data[0];
|
v = data[0];
|
||||||
v = (v << 8) | data[1];
|
v = (v << 8) | data[1];
|
||||||
v = (v << 8) | data[2];
|
v = (v << 8) | data[2];
|
||||||
v &= mask[bit_rem];
|
v &= mask[bit_rem];
|
||||||
v >>= 24 - bit_rem - bitsize;
|
v >>= 24 - bit_rem - bits_read;
|
||||||
}
|
}
|
||||||
else if (bit_left >= 16 && bit_offset >= 9) {
|
else if (bits_left >= 16 && bit_offset >= 9) {
|
||||||
static const unsigned int mask[8] = {
|
static const unsigned int mask[8] = {
|
||||||
0xFFFF,0x7FFF,0x3FFF,0x1FFF,0x0FFF,0x07FF,0x03FF,0x01FF
|
0xFFFF,0x7FFF,0x3FFF,0x1FFF,0x0FFF,0x07FF,0x03FF,0x01FF
|
||||||
};
|
};
|
||||||
const unsigned char* data = &br->data[bit >> 3];
|
const unsigned char* data = &br->data[bit_pos >> 3];
|
||||||
v = data[0];
|
v = data[0];
|
||||||
v = (v << 8) | data[1];
|
v = (v << 8) | data[1];
|
||||||
v &= mask[bit_rem];
|
v &= mask[bit_rem];
|
||||||
v >>= 16 - bit_rem - bitsize;
|
v >>= 16 - bit_rem - bits_read;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
static const unsigned int mask[8] = {
|
static const unsigned int mask[8] = {
|
||||||
0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01
|
0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x01
|
||||||
};
|
};
|
||||||
const unsigned char* data = &br->data[bit >> 3];
|
const unsigned char* data = &br->data[bit_pos >> 3];
|
||||||
v = data[0];
|
v = data[0];
|
||||||
v &= mask[bit_rem];
|
v &= mask[bit_rem];
|
||||||
v >>= 8 - bit_rem - bitsize;
|
v >>= 8 - bit_rem - bits_read;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ fail:
|
|||||||
|
|
||||||
/* writes data to the buffer and moves offsets */
|
/* writes data to the buffer and moves offsets */
|
||||||
int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
mpeg_frame_info info;
|
mpeg_frame_info info;
|
||||||
size_t current_data_size = 0;
|
size_t current_data_size = 0;
|
||||||
size_t current_padding = 0;
|
size_t current_padding = 0;
|
||||||
|
@ -130,7 +130,7 @@ fail:
|
|||||||
|
|
||||||
/* writes data to the buffer and moves offsets, transforming AHX frames as needed */
|
/* writes data to the buffer and moves offsets, transforming AHX frames as needed */
|
||||||
int mpeg_custom_parse_frame_ahx(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
int mpeg_custom_parse_frame_ahx(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
size_t curr_size = 0;
|
size_t curr_size = 0;
|
||||||
size_t file_size = get_streamfile_size(stream->streamfile);
|
size_t file_size = get_streamfile_size(stream->streamfile);
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ fail:
|
|||||||
|
|
||||||
/* writes data to the buffer and moves offsets, transforming EALayer3 frames */
|
/* writes data to the buffer and moves offsets, transforming EALayer3 frames */
|
||||||
int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
int mpeg_custom_parse_frame_ealayer3(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
int ok, granule_found;
|
int ok, granule_found;
|
||||||
ealayer3_buffer_t ib_0 = {0}, ib_1 = {0};
|
ealayer3_buffer_t ib_0 = {0}, ib_1 = {0};
|
||||||
ealayer3_frame_t eaf_0, eaf_1;
|
ealayer3_frame_t eaf_0, eaf_1;
|
||||||
@ -280,7 +280,7 @@ static int ealayer3_parse_frame(mpeg_codec_data* data, int num_stream, ealayer3_
|
|||||||
* (unknown in the first EA-frame but that's ok) */
|
* (unknown in the first EA-frame but that's ok) */
|
||||||
int channels_per_frame = 0;
|
int channels_per_frame = 0;
|
||||||
if (num_stream >= 0) {
|
if (num_stream >= 0) {
|
||||||
channels_per_frame = data->streams[num_stream]->channels_per_frame;
|
channels_per_frame = data->streams[num_stream].channels_per_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure as there is re-parsing in loops */
|
/* make sure as there is re-parsing in loops */
|
||||||
@ -692,7 +692,7 @@ static void ealayer3_copy_pcm_block(uint8_t* outbuf, off_t pcm_offset, int pcm_n
|
|||||||
/* write PCM block directly to sample buffer and setup decode discard (EALayer3 seems to use this as a prefetch of sorts).
|
/* write PCM block directly to sample buffer and setup decode discard (EALayer3 seems to use this as a prefetch of sorts).
|
||||||
* Seems to alter decoded sample buffer to handle encoder delay/padding in a twisted way. */
|
* Seems to alter decoded sample buffer to handle encoder delay/padding in a twisted way. */
|
||||||
static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream, ealayer3_frame_t* eaf) {
|
static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL* stream, mpeg_codec_data* data, int num_stream, ealayer3_frame_t* eaf) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
int channels_per_frame = ms->channels_per_frame;
|
int channels_per_frame = ms->channels_per_frame;
|
||||||
size_t bytes_filled;
|
size_t bytes_filled;
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ fail:
|
|||||||
|
|
||||||
/* reads custom frame header + MPEG data + (optional) PCM block */
|
/* reads custom frame header + MPEG data + (optional) PCM block */
|
||||||
int mpeg_custom_parse_frame_eamp3(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream) {
|
int mpeg_custom_parse_frame_eamp3(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
eamp3_frame_info eaf = {0};
|
eamp3_frame_info eaf = {0};
|
||||||
int ok;
|
int ok;
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ fail:
|
|||||||
|
|
||||||
/* write PCM block directly to sample buffer and setup decode discard (see EALayer3). */
|
/* write PCM block directly to sample buffer and setup decode discard (see EALayer3). */
|
||||||
static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream, eamp3_frame_info * eaf) {
|
static int eamp3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *data, int num_stream, eamp3_frame_info * eaf) {
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
size_t bytes_filled;
|
size_t bytes_filled;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t*
|
|||||||
if (!data) goto fail;
|
if (!data) goto fail;
|
||||||
|
|
||||||
/* keep around to decode */
|
/* keep around to decode */
|
||||||
data->custom = 1;
|
data->custom = true;
|
||||||
data->type = type;
|
data->type = type;
|
||||||
if (cfg)
|
if (cfg)
|
||||||
memcpy(&data->config, cfg, sizeof(mpeg_custom_config));
|
memcpy(&data->config, cfg, sizeof(mpeg_custom_config));
|
||||||
@ -160,25 +160,28 @@ mpeg_codec_data* init_mpeg_custom(STREAMFILE* sf, off_t start_offset, coding_t*
|
|||||||
if (data->channels_per_frame == 2 && channels % 2)
|
if (data->channels_per_frame == 2 && channels % 2)
|
||||||
data->streams_size += 1;
|
data->streams_size += 1;
|
||||||
|
|
||||||
data->streams = calloc(data->streams_size, sizeof(mpeg_custom_stream*));
|
data->streams = calloc(data->streams_size, sizeof(mpeg_custom_stream));
|
||||||
|
if (!data->streams) goto fail;
|
||||||
|
|
||||||
for (int i = 0; i < data->streams_size; i++) {
|
for (int i = 0; i < data->streams_size; i++) {
|
||||||
data->streams[i] = calloc(1, sizeof(mpeg_custom_stream));
|
//data->streams[i] = calloc(1, sizeof(mpeg_custom_stream));
|
||||||
data->streams[i]->m = init_mpg123_handle(); /* decoder not shared as may need several frames to decode)*/
|
//if (!data->streams[i]) goto fail;
|
||||||
if (!data->streams[i]->m) goto fail;
|
data->streams[i].handle = init_mpg123_handle(); /* decoder not shared as frames depend on prev state */
|
||||||
|
if (!data->streams[i].handle) goto fail;
|
||||||
|
|
||||||
/* size could be any value */
|
/* size could be any value */
|
||||||
data->streams[i]->output_buffer_size = sizeof(sample) * data->channels_per_frame * data->samples_per_frame;
|
data->streams[i].output_buffer_size = sizeof(sample) * data->channels_per_frame * data->samples_per_frame;
|
||||||
data->streams[i]->output_buffer = calloc(data->streams[i]->output_buffer_size, sizeof(uint8_t));
|
data->streams[i].output_buffer = calloc(data->streams[i].output_buffer_size, sizeof(uint8_t));
|
||||||
if (!data->streams[i]->output_buffer) goto fail;
|
if (!data->streams[i].output_buffer) goto fail;
|
||||||
|
|
||||||
/* one per stream as sometimes mpg123 can't read the whole buffer in one pass */
|
/* one per stream as sometimes mpg123 can't read the whole buffer in one pass */
|
||||||
data->streams[i]->buffer_size = data->default_buffer_size;
|
data->streams[i].buffer_size = data->default_buffer_size;
|
||||||
data->streams[i]->buffer = calloc(sizeof(uint8_t), data->streams[i]->buffer_size);
|
data->streams[i].buffer = calloc(sizeof(uint8_t), data->streams[i].buffer_size);
|
||||||
if (!data->streams[i]->buffer) goto fail;
|
if (!data->streams[i].buffer) goto fail;
|
||||||
|
|
||||||
data->streams[i]->channels_per_frame = data->channels_per_frame;
|
data->streams[i].channels_per_frame = data->channels_per_frame;
|
||||||
if (i + 1 == data->streams_size && data->channels_per_frame == 2 && channels % 2)
|
if (i + 1 == data->streams_size && data->channels_per_frame == 2 && channels % 2)
|
||||||
data->streams[i]->channels_per_frame = 1;
|
data->streams[i].channels_per_frame = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -201,7 +204,8 @@ static mpg123_handle* init_mpg123_handle(void) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
m = mpg123_new(NULL,&rc);
|
m = mpg123_new(NULL,&rc);
|
||||||
if (rc != MPG123_OK) goto fail;
|
if (rc != MPG123_OK) goto fail;
|
||||||
} else if (rc != MPG123_OK) {
|
}
|
||||||
|
else if (rc != MPG123_OK) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +308,7 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp
|
|||||||
|
|
||||||
/* find max to copy from all streams (equal for all channels) */
|
/* find max to copy from all streams (equal for all channels) */
|
||||||
for (i = 0; i < data->streams_size; i++) {
|
for (i = 0; i < data->streams_size; i++) {
|
||||||
size_t samples_in_stream = data->streams[i]->samples_filled - data->streams[i]->samples_used;
|
size_t samples_in_stream = data->streams[i].samples_filled - data->streams[i].samples_used;
|
||||||
if (samples_to_copy < 0 || samples_in_stream < samples_to_copy)
|
if (samples_to_copy < 0 || samples_in_stream < samples_to_copy)
|
||||||
samples_to_copy = samples_in_stream;
|
samples_to_copy = samples_in_stream;
|
||||||
}
|
}
|
||||||
@ -317,7 +321,7 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp
|
|||||||
samples_to_discard = data->samples_to_discard;
|
samples_to_discard = data->samples_to_discard;
|
||||||
|
|
||||||
for (i = 0; i < data->streams_size; i++) {
|
for (i = 0; i < data->streams_size; i++) {
|
||||||
data->streams[i]->samples_used += samples_to_discard;
|
data->streams[i].samples_used += samples_to_discard;
|
||||||
}
|
}
|
||||||
data->samples_to_discard -= samples_to_discard;
|
data->samples_to_discard -= samples_to_discard;
|
||||||
samples_to_copy -= samples_to_discard;
|
samples_to_copy -= samples_to_discard;
|
||||||
@ -332,8 +336,8 @@ static void decode_mpeg_custom(VGMSTREAM* vgmstream, mpeg_codec_data* data, samp
|
|||||||
|
|
||||||
ch = 0;
|
ch = 0;
|
||||||
for (stream = 0; stream < data->streams_size; stream++) {
|
for (stream = 0; stream < data->streams_size; stream++) {
|
||||||
mpeg_custom_stream *ms = data->streams[stream];
|
mpeg_custom_stream* ms = &data->streams[stream];
|
||||||
sample_t *inbuf = (sample_t *)ms->output_buffer;
|
sample_t* inbuf = (sample_t *)ms->output_buffer;
|
||||||
int stream_channels = ms->channels_per_frame;
|
int stream_channels = ms->channels_per_frame;
|
||||||
int stream_ch, s;
|
int stream_ch, s;
|
||||||
|
|
||||||
@ -379,7 +383,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
|||||||
size_t bytes_done = 0, bytes_filled, samples_filled;
|
size_t bytes_done = 0, bytes_filled, samples_filled;
|
||||||
size_t stream_size = get_streamfile_size(stream->streamfile);
|
size_t stream_size = get_streamfile_size(stream->streamfile);
|
||||||
int rc, ok;
|
int rc, ok;
|
||||||
mpeg_custom_stream *ms = data->streams[num_stream];
|
mpeg_custom_stream* ms = &data->streams[num_stream];
|
||||||
int channels_per_frame = ms->channels_per_frame;
|
int channels_per_frame = ms->channels_per_frame;
|
||||||
|
|
||||||
//;VGM_LOG("MPEG: decode stream%i @ 0x%08lx (filled=%i, used=%i, buffer_full=%i)\n", num_stream, stream->offset, ms->samples_filled, ms->samples_used, ms->buffer_full);
|
//;VGM_LOG("MPEG: decode stream%i @ 0x%08lx (filled=%i, used=%i, buffer_full=%i)\n", num_stream, stream->offset, ms->samples_filled, ms->samples_used, ms->buffer_full);
|
||||||
@ -430,7 +434,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
|||||||
/* feed new raw data to the decoder if needed, copy decoded results to frame buffer output */
|
/* feed new raw data to the decoder if needed, copy decoded results to frame buffer output */
|
||||||
if (!ms->buffer_used) {
|
if (!ms->buffer_used) {
|
||||||
//;VGM_LOG("MPEG: feed new data and get samples\n");
|
//;VGM_LOG("MPEG: feed new data and get samples\n");
|
||||||
rc = mpg123_decode(ms->m,
|
rc = mpg123_decode(ms->handle,
|
||||||
ms->buffer, ms->bytes_in_buffer,
|
ms->buffer, ms->bytes_in_buffer,
|
||||||
(unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled,
|
(unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled,
|
||||||
&bytes_done);
|
&bytes_done);
|
||||||
@ -438,7 +442,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL* stream, mpeg_codec_data*
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//;VGM_LOG("MPEG: get samples from old data\n");
|
//;VGM_LOG("MPEG: get samples from old data\n");
|
||||||
rc = mpg123_decode(ms->m,
|
rc = mpg123_decode(ms->handle,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
(unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled,
|
(unsigned char*)ms->output_buffer + bytes_filled, ms->output_buffer_size - bytes_filled,
|
||||||
&bytes_done);
|
&bytes_done);
|
||||||
@ -494,12 +498,12 @@ void free_mpeg(mpeg_codec_data* data) {
|
|||||||
mpg123_delete(data->m);
|
mpg123_delete(data->m);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i;
|
for (int i = 0; i < data->streams_size; i++) {
|
||||||
for (i=0; i < data->streams_size; i++) {
|
if (!data->streams)
|
||||||
mpg123_delete(data->streams[i]->m);
|
continue;
|
||||||
free(data->streams[i]->buffer);
|
mpg123_delete(data->streams[i].handle);
|
||||||
free(data->streams[i]->output_buffer);
|
free(data->streams[i].buffer);
|
||||||
free(data->streams[i]);
|
free(data->streams[i].output_buffer);
|
||||||
}
|
}
|
||||||
free(data->streams);
|
free(data->streams);
|
||||||
}
|
}
|
||||||
@ -531,7 +535,9 @@ void reset_mpeg(mpeg_codec_data* data) {
|
|||||||
off_t input_offset = 0;
|
off_t input_offset = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < data->streams_size; i++) {
|
for (i = 0; i < data->streams_size; i++) {
|
||||||
mpg123_feedseek(data->streams[i]->m,0,SEEK_SET,&input_offset);
|
if (!data->streams)
|
||||||
|
continue;
|
||||||
|
mpg123_feedseek(data->streams[i].handle,0,SEEK_SET,&input_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -553,13 +559,13 @@ void seek_mpeg(VGMSTREAM* vgmstream, int32_t num_sample) {
|
|||||||
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset + input_offset;
|
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset + input_offset;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i;
|
|
||||||
|
|
||||||
flush_mpeg(data, 1);
|
flush_mpeg(data, 1);
|
||||||
|
|
||||||
/* restart from 0 and manually discard samples, since we don't really know the correct offset */
|
/* restart from 0 and manually discard samples, since we don't really know the correct offset */
|
||||||
for (i = 0; i < data->streams_size; i++) {
|
for (int i = 0; i < data->streams_size; i++) {
|
||||||
//mpg123_feedseek(data->streams[i]->m,0,SEEK_SET,&input_offset); /* already reset */
|
//if (!data->streams)
|
||||||
|
// continue;
|
||||||
|
//mpg123_feedseek(data->streams[i].handle,0,SEEK_SET,&input_offset); /* already reset */
|
||||||
|
|
||||||
/* force first offset as discard-looping needs to start from the beginning */
|
/* force first offset as discard-looping needs to start from the beginning */
|
||||||
if (vgmstream->loop_ch)
|
if (vgmstream->loop_ch)
|
||||||
@ -583,18 +589,21 @@ static void flush_mpeg(mpeg_codec_data* data, int is_loop) {
|
|||||||
int i;
|
int i;
|
||||||
/* re-start from 0 */
|
/* re-start from 0 */
|
||||||
for (i=0; i < data->streams_size; i++) {
|
for (i=0; i < data->streams_size; i++) {
|
||||||
|
if (!data->streams)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* On loop FSB retains MDCT state so it mixes with next/loop frame (confirmed with recordings).
|
/* On loop FSB retains MDCT state so it mixes with next/loop frame (confirmed with recordings).
|
||||||
* This only matters on full loops and if there is no encoder delay (since loops use discard right now) */
|
* This only matters on full loops and if there is no encoder delay (since loops use discard right now) */
|
||||||
if (is_loop && data->custom && !(data->type == MPEG_FSB))
|
if (is_loop && data->custom && !(data->type == MPEG_FSB))
|
||||||
mpg123_open_feed(data->streams[i]->m);
|
mpg123_open_feed(data->streams[i].handle);
|
||||||
data->streams[i]->bytes_in_buffer = 0;
|
data->streams[i].bytes_in_buffer = 0;
|
||||||
data->streams[i]->buffer_full = 0;
|
data->streams[i].buffer_full = 0;
|
||||||
data->streams[i]->buffer_used = 0;
|
data->streams[i].buffer_used = 0;
|
||||||
data->streams[i]->samples_filled = 0;
|
data->streams[i].samples_filled = 0;
|
||||||
data->streams[i]->samples_used = 0;
|
data->streams[i].samples_used = 0;
|
||||||
data->streams[i]->current_size_count = 0;
|
data->streams[i].current_size_count = 0;
|
||||||
data->streams[i]->current_size_target = 0;
|
data->streams[i].current_size_target = 0;
|
||||||
data->streams[i]->decode_to_discard = 0;
|
data->streams[i].decode_to_discard = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->samples_to_discard = data->skip_samples;
|
data->samples_to_discard = data->skip_samples;
|
||||||
@ -639,7 +648,7 @@ void mpeg_set_error_logging(mpeg_codec_data* data, int enable) {
|
|||||||
else {
|
else {
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i < data->streams_size; i++) {
|
for (i=0; i < data->streams_size; i++) {
|
||||||
mpg123_param(data->streams[i]->m, MPG123_ADD_FLAGS, MPG123_QUIET, !enable);
|
mpg123_param(data->streams[i].handle, MPG123_ADD_FLAGS, MPG123_QUIET, !enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ typedef struct {
|
|||||||
size_t bytes_in_buffer;
|
size_t bytes_in_buffer;
|
||||||
int buffer_full; /* raw buffer has been filled */
|
int buffer_full; /* raw buffer has been filled */
|
||||||
int buffer_used; /* raw buffer has been fed to the decoder */
|
int buffer_used; /* raw buffer has been fed to the decoder */
|
||||||
mpg123_handle *m; /* MPEG decoder */
|
|
||||||
|
mpg123_handle* handle; /* MPEG decoder */
|
||||||
|
|
||||||
uint8_t *output_buffer; /* decoded samples from this stream (in bytes for mpg123) */
|
uint8_t *output_buffer; /* decoded samples from this stream (in bytes for mpg123) */
|
||||||
size_t output_buffer_size;
|
size_t output_buffer_size;
|
||||||
@ -33,7 +34,7 @@ typedef struct {
|
|||||||
|
|
||||||
struct mpeg_codec_data {
|
struct mpeg_codec_data {
|
||||||
/* regular/single MPEG internals */
|
/* regular/single MPEG internals */
|
||||||
uint8_t *buffer; /* raw data buffer */
|
uint8_t* buffer; /* raw data buffer */
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
size_t bytes_in_buffer;
|
size_t bytes_in_buffer;
|
||||||
int buffer_full; /* raw buffer has been filled */
|
int buffer_full; /* raw buffer has been filled */
|
||||||
@ -49,12 +50,12 @@ struct mpeg_codec_data {
|
|||||||
int sample_rate_per_frame;
|
int sample_rate_per_frame;
|
||||||
|
|
||||||
/* custom MPEG internals */
|
/* custom MPEG internals */
|
||||||
int custom; /* flag */
|
bool custom; /* flag */
|
||||||
mpeg_custom_t type; /* mpeg subtype */
|
mpeg_custom_t type; /* mpeg subtype */
|
||||||
mpeg_custom_config config; /* config depending on the mode */
|
mpeg_custom_config config; /* config depending on the mode */
|
||||||
|
|
||||||
size_t default_buffer_size;
|
size_t default_buffer_size;
|
||||||
mpeg_custom_stream **streams; /* array of MPEG streams (ex. 2ch+2ch) */
|
mpeg_custom_stream* streams; /* array of MPEG streams (ex. 2ch+2ch) */
|
||||||
size_t streams_size;
|
size_t streams_size;
|
||||||
|
|
||||||
size_t skip_samples; /* base encoder delay */
|
size_t skip_samples; /* base encoder delay */
|
||||||
|
@ -438,7 +438,6 @@ static void buffer_close(BUFFER_STREAMFILE* sf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STREAMFILE* open_buffer_streamfile(STREAMFILE* sf, size_t buf_size) {
|
STREAMFILE* open_buffer_streamfile(STREAMFILE* sf, size_t buf_size) {
|
||||||
uint8_t* buf = NULL;
|
|
||||||
BUFFER_STREAMFILE* this_sf = NULL;
|
BUFFER_STREAMFILE* this_sf = NULL;
|
||||||
|
|
||||||
if (!sf) goto fail;
|
if (!sf) goto fail;
|
||||||
@ -446,9 +445,6 @@ STREAMFILE* open_buffer_streamfile(STREAMFILE* sf, size_t buf_size) {
|
|||||||
if (buf_size == 0)
|
if (buf_size == 0)
|
||||||
buf_size = STREAMFILE_DEFAULT_BUFFER_SIZE;
|
buf_size = STREAMFILE_DEFAULT_BUFFER_SIZE;
|
||||||
|
|
||||||
buf = calloc(buf_size, sizeof(uint8_t));
|
|
||||||
if (!buf) goto fail;
|
|
||||||
|
|
||||||
this_sf = calloc(1, sizeof(BUFFER_STREAMFILE));
|
this_sf = calloc(1, sizeof(BUFFER_STREAMFILE));
|
||||||
if (!this_sf) goto fail;
|
if (!this_sf) goto fail;
|
||||||
|
|
||||||
@ -463,7 +459,8 @@ STREAMFILE* open_buffer_streamfile(STREAMFILE* sf, size_t buf_size) {
|
|||||||
|
|
||||||
this_sf->inner_sf = sf;
|
this_sf->inner_sf = sf;
|
||||||
this_sf->buf_size = buf_size;
|
this_sf->buf_size = buf_size;
|
||||||
this_sf->buf = buf;
|
this_sf->buf = calloc(buf_size, sizeof(uint8_t));
|
||||||
|
if (!this_sf->buf) goto fail;
|
||||||
|
|
||||||
this_sf->file_size = sf->get_size(sf);
|
this_sf->file_size = sf->get_size(sf);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user